meta-controller
v2.0.2
Published
meta-controller
Downloads
18
Readme
What is meta-controller?
meta-controller is a library for creating NodeJs REST APIs using TypeScript decorators. It is a wrapper for the popular express framework. It's designed to be a lightweight alternative to NestJs.
Installation
Install the meta-controller package from npm.
npm install meta-controller
Basic Usage
Create a REST API controller by using the JsonController(<route>)
decorator and define routes by using the @Route(<http method>, <path>)
decorator. Routes can be synchronous or asynchronous. Route paramaters are automatically transformed (meta-transformer) and validated (meta-validator).
@JsonController("/basic")
class WidgetController {
@Route(HttpMethod.GET)
get(): Widget {
return testWidget;
}
}
const expressApp = express();
MetaController.useExpressServer(expressApp, {
isUseCors: true,
controllerClassTypes: [
WidgetController
]
});
apiServer = http.createServer(expressApp);
apiServer.listen(4500);
Initialization
Pass an instance of express to MetaController.useExpressServer()
to initialize meta-controller.
const expressApp = express();
MetaController.useExpressServer(expressApp, {
// options
});
The following initialization options are available.
| Option | Description | |----------------------|----------------------------------------------------------------------------------| | isDebug | Log any errors to stdout | | routePrefix | Add a global route prefix (e.g. /api) | | isUseCors | Add CORS to all routes | | isSaveRawBody | Add the raw body to the request object (request.rawBody) | | controllerClassTypes | An array of class controllers that will be added as express routes) | | authorizationHandler | A user supplied function that determines if the request has been authorized | | currentUserHandler | A user supplied function that retrieves the user (if any) of the current request | | customErrorHandler | A global custom error handler | | globalMiddleware | Any optional global middleware |
Route Parameters
Controllers may accept all standard REST type parameters. Parameters are automatically transformed or cast to the specified type.
HTTP Request Body
@Route(HttpMethod.POST, "/body")
myRoute(@Body() widget: Widget) {
// ... business logic
}
Route Parameters
// Example: https://localhost/api/param/5
@Route(HttpMethod.GET, "/param/:id")
myRoute(@Param("id") id: number) {
// ... business logic
}
Route Query Parameters
// Example: https://localhost/api/query-param?myQueryParam=test
@Route(HttpMethod.POST, "/query-param")
myRoute(@QueryParam("myQueryParam") myQueryParam: string) {
// ... business logic
}
HTTP Request Headers
@Route(HttpMethod.GET, "/header-param")
myRoute(@HeaderParam("TestHeader") testHeader: string) {
// ... business logic
}
Authorization
You can require authorization on a per-controller basis by specifying an authorizationHandler()
and using the @Authorization()
decorator.
const expressApp = express();
MetaController.useExpressServer(expressApp, {
authorizationHandler: (request, response, roles): boolean => {
// ... business logic
// Return true for authorized, false for unauthorized
return true;
}
});
@Authorize(["Admin"])
@JsonController("/secure")
class SecureController {
@Route(HttpMethod.GET, "/protected-route")
myRoute() {
// ... business logic
}
}
If you also add a currentUserHandler()
you can inject the current user using the CurrentUser()
decorator.
class User {
userName: string = "TestUser";
}
const testUser = new User();
const expressApp = express();
MetaController.useExpressServer(expressApp, {
currentUserHandler: (request, response): User => {
// ... business logic
return testUser;
}
});
@Route(HttpMethod.GET, "/current-user")
getCurrentUser(@CurrentUser() currentUser: User): User {
// ... business logic
return currentUser;
}
Error Handling
You can throw errors along with associated HTTP error codes.
@Authorize(["Admin"])
@JsonController("/secure")
class SecureController {
@Route(HttpMethod.GET, "/protected-route")
myRoute() {
throw new HttpError(HttpStatus.UNAUTHORIZED, "Unauthorized request");
}
}
If no HTTP error code is specified then meta-controller defaults to using HTTP status 500 (INTERNAL_SERVER_ERROR).
@Route(HttpMethod.POST, "/body")
myRoute(@Body() widget: Widget) {
// Returns HTTP status 500 - INTERNAL_SERVER_ERROR
throw new Error("An unknown error occurred");
}
Decorator Reference
| Decorator | Type | Description | |-------------------------------|-----------|------------------------------------------------------| | @Authorize() | Class | Controller requires authorization | | @JsonController() | Class | Create a JSON controller | | @Body() | Parameter | Inject a JSON body parameter | | @CurrentUser() | Parameter | Inject the current user | | @EncodedJwtToken() | Parameter | Inject the encoded JWT token string | | @HeaderParam() | Parameter | Inject a header from the HTTP request | | @Param() | Parameter | Inject a route parameter (e.g. /user/:id) | | @QueryParam() | Parameter | Inject a query parameter (e.g. /route?my-param=test) | | @Request() | Parameter | Inject the entire request object | | @Response() | Parameter | Inject the entire response object | | @Route(<http method, path>) | Property | Define a route on the controller |