Skip to content
Hayley edited this page Sep 12, 2020 · 4 revisions

Routes are user defined objects which define how to respond to HTTP requests. All routes must be a child of the Route class and follow the same basic template

class UserDefinedRoute : public Route {
// All methods and attributes which FireStorm needs to use/modify must be public
public:
  // Required for the Router middleware
  UriArgs uri_args;

  Outcome middlewares() {
    return MiddleWares<UserDefinedRoute>()
        .add(new Router<UserDefinedRoute>(HTTP_GET_METHOD, {"/"}))
        .outcome(*this);
  }

  Response response() {
    return plain("Hello World!", HTTP_STATUS_OK);
  }
};

The important bits here are the middlewares() and route() methods.

Registering middlewares

Middlewares for a route are not only defined in the route but in order to not break the C++ static typing system must also be called by from inside the route hence why middlewares are defined using the a middlewares() method. The signature for the method is as follows

Outcome middlewares();

The Outcome varient which is returned is the collective outcome of all the middlewares. This means that if any of the middleware for that route were to fail then middlewares() would return an Outcome::Failure.

If the middlewares() method is not defined then the default is to always return Outcome::Success.

The MiddleWares<R> object

Not to be confused with MiddleWare<R>, MiddleWares<R> is a helper object designed to simplify the process mentioned above by providing some methods to automate middleware registration. The add() method adds a middleware to be handled and the outcome() method returns a single outcome for all the middlewares where if any of the added middleware returned an Outcome::Failure then outcome() will return an Outcome::Failure. An example of using MiddleWares<R> is as follows

MiddleWares<UserDefinedRoute>()
  .add(new Router<UserDefinedRoute(HTTP_GET_METHOD, {"/"}))
  .add(new UserDefinedMiddleWare<UserDefinedRoute>()
  .outcome(*this)

You'll notice that outcome() takes a pointer to the current object (*this), this is how the current route is passed through to the middleware so that it can be modified before returning a response.

Note: Middlewares will be executed in the order they are specified, therefore it's always a good idea to put a router first to avoid situations where a middleware is throwing an error for all routes executed after the current one (remember routes are executed in the order they are registed).

Returning a response

If all the middlewares have returned Outcome::Success then the response() method is called for that route. The response method's signature is as follows

Response response();

The returned Response will be sent to the client (see Responses for more information on creating responses)

If the response() method is not defined then the default is to return a 500 Internal Server Error.

Clone this wiki locally