Skip to main content

Defining Routes

The Route Class (using @Route)

In RapidREST, the @Route() decorator is used at the class level to identify a set of HTTP request handlers at a given base path. In other frameworks, the @Route class is equivalent to an app router. The @Route decorator takes a single paths argument which can be a single string or an Array<string> that includes each base path that the class' methods will respond to.

The following is an example of a route class.

import {RouteDecorators} from '@rapidrest/service-core';
const {Route} = RouteDecorators;

@Route('/pets')
export class PetRoute {}

It should be noted that the the underlying HTTP engine does not yet have any bound request handlers for the /pets path. There must be at least one HTTP method function in a route class for the framework to register the endpoint.

Below is an example of a route class that has multiple base paths configured. When multiple paths are configured, the framework automatically registers each HTTP request handler function for each of the desired base paths.

import { RouteDecorators } from '@rapidrest/service-core';
const {Route} = RouteDecorators;

@Route(['/pet','/pets','/companions'])
export class PetRoute {}

API-Versioned Routes (using @ApiRoute)

@ApiRoute(paths, version?) is a drop-in alternative to @Route that prepends /api (or /api/v{version}, if a version is given) to every path. Everything else about the class — handler functions, sub-paths, @Auth, @Protect — works identically.

import { RouteDecorators } from '@rapidrest/service-core';
const { ApiRoute } = RouteDecorators;

@ApiRoute('/pets')
export class PetRoute {}
// GET /pets -> GET /api/pets
@ApiRoute('/pets', 2)
export class PetRouteV2 {}
// GET /pets -> GET /api/v2/pets

The CLI's --api [version] flag (available on generate route, generate server, and generate default-route) scaffolds classes using @ApiRoute instead of @Route — see CLI Reference.

HTTP Handler Functions

As mentioned above, RapidREST does not bind a route until a HTTP handler function is defined in a route class. To define an HTTP handler function it is as easy as decorator any function with the HTTP method (or verb) desired for a given endpoint.

Let's update our previous example to add a basic Get() handler function.

import { RouteDecorators } from '@rapidrest/service-core';
const { Get } = RouteDecorators;

@Route('/pets')
export class PetRoute {
@Get()
async findPets() {
/* ... */
}
}

Now that there exists a handler function in the PetRoute class the framework will automatically register and bind the HTTP route GET /pets to the PetRoute.findPets() function. Each HTTP method decorator takes an optional sub-path, which is appended to the class's @Route base path (shown below).

import { RouteDecorators } from '@rapidrest/service-core';
const { Get } = RouteDecorators;

@Route('/pets')
export class PetRoute {
@Get()
async findPets() {
/* ... */
}

@Get('/:id')
async findPet() {
/* ... */
}
}

You also can stack more than one HTTP-method decorator on the same handler if it should respond to multiple methods identically (shown below).

import { RouteDecorators } from '@rapidrest/service-core';
const { Post, Put } = RouteDecorators;

@Route('/pets')
export class PetRoute {
@Post()
@Put()
async createOrUpdate(obj: Pet) {
/* ... */
}
}

HTTP Method Decorators

The following table shows all HTTP methods that RapidREST provides a built-in decorator for.

HTTP MethodDecorator
DELETE@Delete(path: string)`
GET@Get(path: string)`
HEAD@Head(path: string)`
OPTIONS@Options(path: string)`
PATCH@Patch(path: string)`
POST@Post(path: string)`
PUT@Put(path: string)`

Alternatively, the @Method(method: string | string[], path: string) decorator can be used for other HTTP methods that do not have their own decorator or if you'd like to register multiple methods at once.

Handler return values

A handler's return value becomes the JSON response body. Async handlers work as expected:

@Get('/:id')
async getPet(@Param('id') id: string): Promise<Pet | null> {
return this.petService.findById(id);
}

Throwing inside a handler (or a @Before/@Validate step) results in an error response. See Lifecycle & Validation for where in the pipeline that happens.

WebSocket Support

RapidREST also supports WebSockets via the @WebSocket(path?) decorator. This decorator performs automatic upgrades of the connection instead of returning an HTTP response.

import { RouteDecorators } from '@rapidrest/service-core';
const { Socket, WebSocket } = RouteDecorators;

@Route('/connect')
export class PetRoute {
@WebSocket()
async upgrade(@Socket socket: any) {
/* ... */
}
}