Http Response

Just like with an HTTP request, HttpCall object is what you'd use for sending responses back to a client.

Returning Response Payload

You can send response back to the client with a "payload" by using one of reply() or replyAsJson() methods. There are some overloaded variants of these methods as well.

  • reply(payload: T? = null, statusCode: Int = 200)

Returns a payload back to the client in a UTF-8 encoded HTML format. The payload is first converted to a string by callingtoString() method on it. You can pass a status code if you want it to be something other than the default 200.

  • replyAsJson(payload: T? = null, statusCode: Int = 200)

Returns the given payload to the client in a JSON format.

  • replyAsJson(obj: JsonSerializable, statusCode: Int = 200)

A convenient method for returning an object that implements dev.alpas.JsonSerializable interface. The returned format is JSON, of course!

  • acknowledge(statusCode: Int = 204)

Sometimes you may just want to acknowledge a request call and not necessarily have any payload to return. In such situations you can use this convenient method. Since, the acknowledgement without a payload is mostly applicable in a JSON request, the content type is set to JSON when using this method.

  • status(code: Int)

Use this method if you want to set/change the status code of your response after calling one of the above methods.

Rendering Templates

Instead of returning a string or a JsonSerializable object, you can render a template instead using one of render methods.

  • render(templateName: String, args: Map<String, Any?>?, statusCode: Int)

Renders a template of the given name with some optional contextual arguments for the template. The location of the template, by default, is under resources/templates. You can change the default location by overriding templatesDirectory property of dev.alpas.view.ViewConfig class.

Aborting Calls

Instead of returning a valid response, you may want to abort a call and return an error response back to the client. You can do so by using abort() or abortUnless() method.

  • abort(statusCode: Int, message: String?, headers: Map<String, String>): Nothing

Aborts the call and sends back an exception appropriate for the given status code. 404 code is converted to NotFoundHttpException, 405 to MethodNotAllowedException, 500 to InternalServerException, and all other exceptions to HttpException.

  • abortUnless(condition: Boolean, statusCode: Int, message: String?, headers: Map<String, String>)

Aborts the call if the given condition is false.

  • abortIf(condition: Boolean, statusCode: Int, message: String?, headers: Map<String, String>)

Aborts the call if the given condition is true.

/tip/ You can simply throw a subclass of dev.alpas.exceptions.HttpException if you want to have more control over the exception being thrown when aborting a call.

Headers

Attaching Headers

Use addHeader(key: String, value: String) to attach a header or addHeaders(headers: Map<String, String>) to attach multiple headers to an outgoing response. You can call these methods multiple times to attach additional headers.


fun index(call: HttpCall) {
    call.apply {
        addHeader("Content-Type", "application/json")
        addHeader("X-H1", "Some Value")
        addHeader("X-H2", "Some Value")
    }.reply("Headers Galore!")
 }

Content Type

  • asHtml()

Set the response's content type to text/html; charset=UTF-8.

  • asJson()

Set response's content type to application/json; charset=UTF-8.

  • contentType(type: String)

Set response's content type to the given type.


fun index(call: HttpCall) {
    val content = mapOf("say" to "Hello, Json!").toJson()
    call.reply(content).asJson()   
    // alternatively
    call.replyAsJson(content)
 }

Cookies

Cookie is a small piece of information that gets sent with a response back to the client. The client would then return unexpired cookies back to the server in the subsequent requests.

/info/ Alpas encrypts and signs almost all of your outgoing cookies and decrypts them when it receives a request. If the cookies are changed by the client, they will be invalidated and removed automatically as well.

/tip/ You can return the names of the cookies that you don't want to be encrypted by extending SessionConfig class and then overriding encryptExcept value.

Attaching Cookies

Send a cookie back to the client by calling the add() method on the cookie property, which is an instance of CookieJar.

  • fun add(name: String, value: String?, lifetime: Duration, path: String?, domain: String?, secure: Boolean, httpOnly: Boolean)

    • name - The name of the cookie. Must not be empty.
    • value - The payload of the cookie.
    • lifetime - Maximum age for this cookie. Default is -1 second. A negative duration means this cookie will be deleted when the browser exits. A zero duration means the cookie will be deleted right away.
    • path - The path for the cookie to which the client should return the cookie. Default is null.
    • domain - The domain within which the cookie should be presented. Default is null.
    • secure - Whether the browser should return this cookie only using a secure protocol, such as HTTPS or SSL, or not. Default is false.
    • httpOnly - Whether to mark this cookie as HttpOnly or not. This directs a browser to not expose this cookie to client-side scripting code. Default is true.

// ...

call.cookie.add("some_name", "some_value")
// Alternatively, since `CookieJar` implements the `set()` operator method,
// you can also do.
call.cookie["some_name"] = "some_value"

// ...

Forgetting Cookies

You can forget/ clear a cookie by calling forget() method and passing the name of the cookie that you would want to clear. Optionally, you can also pass the cookie's path and/or the domain.


// ...

call.cookie.forget("some_name")

// ...

Redirects

The HttpCall#redirect() method returns an implementation of dev.alpas.http.Redirectable, which has everything you need to redirect a call to somewhere else—either internal or external.

  • fun to(to: String, status: Int = 302, headers: Map<String, String> = emptyMap())

Redirects a call to the given to url.

  • fun back(status: Int = 302, headers: Map<String, String> = emptyMap(), default: String = "/")

Redirects a call to the previous location. The previous location is determined by first looking at the referral header in the request. If it is null then it looks the value of a previous url from the session. Alpas automatically saves this location in the current user session for every request. If both of these values are absent, then it will redirect to the given default location.

/tip/ This method is very handy for sending a user back to a form if the form input is invalid. In fact, this is exactly what Alpas does to redirect a user back to the previous page if a form fails the validation checks.

  • fun intended(default: String = "/", status: Int, headers: Map<String, String>)

Redirects a call to the location that a user initially intended to go to. Let's say a user is trying to access a page that requires the user to be authenticated. In this case, if user isn't authenticated, we would normally take them first to a login page so that they could be authenticated. After they successfully login, we would want to take them to the page they originally intended. In this case you'd want to use intended() method.

  • fun toRouteNamed(name: String, params: Map<String, Any>, status: Int, headers: Map<String, String>)

Redirects a call to a route that matches the given name. params is a map of parameters for that route.


fun index(call: HttpCall) {
    call.redirect().toRouteNamed("docs.showPage", mapOf("page" to "http-response"))
}

  • fun home(status: Int = HttpStatus.MOVED_TEMPORARILY_302, headers: Map<String, String>)

A convenient method that redirects a call to a route named home, if exists. If not, it redirects to /.

  • fun toExternal(url: String, status: Int = 302, headers: Map<String, String>)

Redirects a call to the given external url.

/alert/ Some redirects methods such as back(), intended() etc. depend on sessions and hence they are available only for the routes that have SessionStart middleware applied—either applied individually or using web middleware group.