Creating Responses

Strings & Arrays

All routes and controllers should provide back a response to the user's browser. OstroJS allows you to return replies in a variety of ways. Returning a string from a route or controller is the most basic answer. The framework will transform the string to a complete HTTP response automatically:

Route.get('/', function ({ response }) {
    response.send('Hello World');
});

You may now return arrays from your routes and controllers in addition to strings. The framework will transform the array into a JSON response automatically:

Route.get('/', function ({ response }) {
    response.send([1, 2, 3]);
});

You may change the response's HTTP status code and headers by returning a complete Response object. The @ostro/http/response class, which provides a range of methods for generating HTTP replies, is inherited by a Response instance.

Route.get('/home', function ({ response }) {
	response.header('Content-Type', 'text/plain')
    response.send('Hello World', 200);
});

Attaching Headers To Responses

Keep in mind that most response methods may be chained together to create response instances quickly. For example, before sending the answer back to the user, you might use the header method to add a sequence of headers to it:

return response
            .header('Content-Type', $type)
            .header('X-Header-One', 'Header Value')
            .header('X-Header-Two', 'Header Value')
            .send(content);

You can also specify an array of headers to be added to the response using the withHeaders method:

return response
            .withHeaders({
                'Content-Type' : $type,
                'X-Header-One' : 'Header Value',
                'X-Header-Two' : 'Header Value',
            }).send(content);

Attaching Cookies To Responses

The cookie method may be used to attach a cookie to an outgoing @ostro/http/response object. This method should be passed the name, value, and amount of minutes the cookie should be deemed valid:

response.cookie(
    'name', 'value', $minutes
);
return response.send('Hello World')

There are a couple additional parameters that the cookie method accepts, but they aren't used very often. These parameters serve the same purpose and have the same value as the ones passed to NodeJS's native setcookie method:

response.cookie(
    'name', 'value', $minutes, $path, $domain, $secure, $httpOnly
);
return  response.send('Hello World')

Expiring Cookies Early

You may use the  request cookie expire function to expire a cookie if you don't already have an instance of the outgoing response:

cookie.expire('name');

Cookies & Encryption

By default, all cookies produced by OstroJS are encrypted and signed, making them impossible for the client to modify or access. You may utilise the $except property of the app/http/middleware/encryptCookies middleware, which is located in the app/http/middleware directory, to deactivate encryption for a subset of cookies created by your application:

/**
 * The names of the cookies that should not be encrypted.
 *
 * @var array
 */
$except = [
    'cookie_name',
];

Redirects

Redirect replies are @ostro/http/response objects that include the appropriate headers for redirecting the user to another URL. A RedirectResponse instance can be created in a variety of ways:

Route.get('/dashboard', function ({ redirect }) {
    redirect.to('home/dashboard');
});

When a submitted form is invalid, you may want to return the user back to their prior position. You may accomplish this by use the back function. Because this functionality makes use of the session, ensure that the route using the back function uses the web middleware group:

Route.post('/user/profile', function ({ redirect }) {
    // Validate the request...

    redirect.back().withInput();
});

Redirecting To Named Routes

When you call the redirect without any parameters, you'll get an instance of @ostro/routing/redirector, which you may use to call any method on. You may use the route method to produce a RedirectResponse to a specified route, for example:

redirect.route('login');

If your route includes parameters, you may give them to the route method as the second argument:

// For a route with the following URI: /profile/{id}

redirect.route('profile', {'id' : 1});

Redirecting To External Domains

It's possible that you'll need to redirect to a domain outside of your application at some point. You may do so by using the away method, which generates a RedirectResponse with no further URL encoding, validation, or verification:

redirect.away('https://www.google.com');

Redirecting With Flashed Session Data

Usually, redirecting to a new URL and flashing data to the session happen at the same moment. When you flash a success message to the session after successfully completing an activity, this is often done. Create a RedirectResponse object and flash data to the session in a single, fluent method chain for convenience:

Route.post('/user/profile', function ({ redirect }) {
    // ...
    redirect.to('dashboard').with('status', 'Profile updated!');
});

You can show the flashing message from the session after the user is redirected. For instance, consider the following Blade syntax:

<% if (helpers.session('status')) { %>
    <div class="alert alert-success">
        <%= helpers.session('status') %>
    </div>
<% } %>

Redirecting With Input

Before redirecting the user to a new location, you may use the withInput function offered by the RedirectResponse class to save the current request's input data to the session. If the user encounters a validation error, this is usually done. You can simply recover the input once it has been flashed to the session on the next request to repopulate the form:

redirect.back().withInput();

Other Response Types

Other sorts of response instances can be generated using the response object. When the response is invoked without any parameters, an @ostro/contracts/routing/responseFactory contract implementation is returned. This contract has a number of options for creating replies.

View Responses

Use the view method if you require control over the response's status and headers but also need to return a view as the response's content:

response.view('hello', $data, 200).header('Content-Type', $type);

Of course, you may use the response view method if you don't need to pass a custom HTTP status code or custom headers.

JSON Responses

The json method will set the Content-Type header to application/json and use the JSON.stringify NodeJS function to convert the supplied array to JSON:

return response.json({
    'name' :  'Abigail',
    'state':  'CA',
});

You may use the json method in conjunction with the withCallback method to generate a JSONP response:

return response
            .jsonp({'name' :  'Abigail', 'state' :  'CA'], request.input('callback'))

File Downloads

The download method may be used to provide a response that instructs the user's browser to download the file at the specified location. The second input to the download function is a filename, which will decide the filename that the user sees while downloading the item. Finally, as the method's third argument, you may send an array of HTTP headers:

return response.download($pathToFile);

return response.download($pathToFile, $name, $headers);

Response Macros

You may use the macro method on the Response class to construct a custom response that you can reuse in a variety of your routes and controllers. This function is often called from one of your application's service providers' boot method, such as the app/providers/appServiceProvider service provider:

const ServiceProvider = require('@ostro/support/serviceProvider')
const Response = require('@ostro/foundation/http/response')
class AppServiceProvider extends ServiceProvider {

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    boot() {
        Response.macro('caps', function($value) {
            return $value.capitalize();
        });
    }
}
module.exports = AppServiceProvider

The first parameter to the macro function is a name, and the second argument is a closure. When invoking the macro name from a ResponseFactory implementation or the response helper, the macro's closure will be executed:

response.caps('foo')