Skip to content

Latest commit

 

History

History
242 lines (173 loc) · 7.04 KB

README.md

File metadata and controls

242 lines (173 loc) · 7.04 KB

Response

What is returned by the Route method will be sent to the client as the response. The Routing section touched this briefly, here we will go over all the options of respoding to a request.

Responding to Routes

Errors

Response Factories

Default Error/Response Codes

Responding to Routes

All returned and resolved values that are not Response objects will be converted to Response objects at some point. When this happens, if your route does not specify the type of response, a default will be chosen from the context. The defaults and their conditions are-

200 - Is the default for any resolved/returned request with a payload.

204 - Is the default for any resolved/returned request without a payload.

400 - Is the default for any request that has missing required injectables or fails DTO validation.

500 - Is the default for any rejected request, thrown error, failed rule, or failed resource resolution.

For more control over the status code, the generically named Response object should be used. When creating a response, you should provide the http status code as well as the data to be sent to the client.

import {Route, Response} from 'expresskit';

export class FooRouter {
  @Route('GET', '/foo')
  public static fooRoute() {
    return 'foo';

    // is the same as

    return new Response(200, 'foo');

    // is the same as

    return Promise.resolve('foo');

    // is the same as

    return Promise.resolve(new Response(200, 'foo'));
  }
}

Errors

To respond with an error you can simple return a response with an error code.

return new Response(500, 'something bad happened');

Under two conditions will an error be assumed. Those conditions are if the route encounters a Thrown Error or Rejected Promise. In these cases, the status code will default to a 500 Internal Server Error. However, a thrown Error is not the same as a thrown Resposne.

import {Route} from 'expresskit';

export class FooRouter {
  @Route('GET', '/foo')
  public static fooRoute() {
    throw new Error('An error occured')

    // is NOT the same as

    return Promise.reject('An error occured');
  }
}

If an error is thrown, it assumed that there is an actual runtime error and the stacktrace will be returned. You can throw intended errors by throwing a Response.

import {Route, Response} from 'expresskit';

export class FooRouter {
  @Route('GET', '/foo')
  public static fooRoute() {
    return new Response(500, 'An error occured');

    // is the same as

    throw new Response(500, 'An error occured')

    // is the same as

    return Promise.reject('An error occured');

    // is the same as

    return Promise.reject(new Response(500, 'An error occured'));
  }
}

Response Factories

For convenience sake, some response factories are available. Each response factory defaults the response code as well as the response value if not given.

import {Route, Response} from 'expresskit';

export class FooRouter {
  @Route('GET', '/foo')
  public static fooRoute() {
    return Response.NotFound(`Couldn't find Foo`);
  }
}

The available factories and their values are-

Factory Function Resposne Code Default Response Value
Ok 200 Ok
Created 201 Created
Accepted 202 Accepted
None 204
BadRequest 400 Bad Request
Unauthorized 401 Unauthorized
PaymentRequired 402 Payment Required
Forbidden 403 Forbidden
NotFound 404 Not Found
MethodNotAllowed 405 Method Not Allowed
NotAcceptable 406 Not Acceptable
Conflict 409 Conflict
Gone 410 No Long Available
Error 500 Internal Server Error
NotImplemented 501 Not Implemented
BadGateway 502 Bad Gateway
TemporarilyUnavailable 503 Temporarily Unavailable
GatewayTimeout 504 GatewayTimeout

Default Error/Response Codes

Returning a Response should be used if the route or rule may return different types of responses. For everything else, use the ResponseCode and ErrorCode decorators if you don't intended to use the defaults. These decorators override the default response codes for success and error responses. Only one default response code and error code can be used for a particular Route, Rule, or Resolver.

import {Route, Param, Resolver, ResponseCode, ErrorCode} from 'expresskit';

export class WidgetRouter {

  @Resolver('Widget')
  @Route('GET', '/widget/:id')
  @ResponseCode(200) // Redundant but you get the point
  @ErrorCode(404)
  public static getWidget(@Param('id') id: string): Promise<Widget> {
    let widget = /* get widget from database*/;

    if(widget) {
      return Promise.resolve(widget);
    } else {
      return Promise.reject(`Widget by id '${id}' not found.`);
    }
  }
}

In the above example, the getWidget method is both a Route and a Resource Resolver. If another route wants to resolve the Widget resource for that route using this resolver, a 404 error will be returned that the resolution fails.

import {Route, Param, Resolver, ResponseCode, ErrorCode} from 'expresskit';

export class WidgetRouter {

  @Resolver('Widget')
  @Route('GET', '/widget/:id')
  @ResponseCode(200) // Redundant but you get the point
  @ErrorCode(404)
  public static getWidget(@Param('id') id: string): Promise<Widget> {
    let widget = /* get widget from database*/;

    if(widget) {
      return Promise.resolve(widget);
    } else {
      return Promise.reject(`Widget by id '${id}' not found.`);
    }
  }

  // If `Widget` cannot be resolved, a 404 error will be returned
  @Route('PUT', '/widget/:id')
  public static updateWidget(@Resource('Widget') widget: Widget) {
    // update widget
  }

Keep Reading

Routing

Response

Middleware

Resource Resolutions

Rules

DTOs

More Links

Expresskit Seed Project

Github

Issues

NPM

Twitter