Parsing requests

LoopBack 4 uses the Content-Type header and requestBody of the OpenAPI specto parse the body of http requests. Please seeParsing requests for more details.

The @loopback/rest module ships a set of built-in body parsers:

  • json: parses the http request body as a json value (object, array, string,number, boolean, null)
  • urlencoded: decodes the http request body from‘application/x-www-form-urlencoded’
  • text: parses the http request body as a string
  • stream: keeps the http request body as a stream without parsing
  • raw: parses the http request body as a BufferTo support more media types, LoopBack defines extension points to plug in bodyparsers to parse the request body. LoopBack’s request body parsing capabilitycan be extended in the following ways:

Adding a new parser

To add a new body parser, follow the steps below:

  • Define a class that implements the BodyParser interface:
  1. /**
  2. * Interface to be implemented by body parser extensions
  3. */
  4. export interface BodyParser {
  5. /**
  6. * Name of the parser
  7. */
  8. name: string | symbol;
  9. /**
  10. * Indicate if the given media type is supported
  11. * @param mediaType - Media type
  12. */
  13. supports(mediaType: string): boolean;
  14. /**
  15. * Parse the request body
  16. * @param request - http request
  17. */
  18. parse(request: Request): Promise<RequestBody>;
  19. }

A body parser implementation class will be instantiated by the LoopBack runtimewithin the context and it can leverage dependency injections. For example:

  1. export class JsonBodyParser implements BodyParser {
  2. name = 'json';
  3. private jsonParser: BodyParserMiddleware;
  4. constructor(
  5. @inject(RestBindings.REQUEST_BODY_PARSER_OPTIONS, {optional: true})
  6. options: RequestBodyParserOptions = {},
  7. ) {
  8. const jsonOptions = getParserOptions('json', options);
  9. this.jsonParser = json(jsonOptions);
  10. }
  11. // ...
  12. }

See the complete code athttps://github.com/strongloop/loopback-next/blob/master/packages/rest/src/body-parsers/body-parser.json.ts.

  • Bind the body parser class to your REST server/application:For example,
  1. server.bodyParser(XmlBodyParser);

The bodyParser api binds XmlBodyParser to the context with:

  • key: request.bodyParser.XmlBodyParser
  • tag: request.bodyParserPlease note that newly added body parsers are always invoked before the built-inones.

Contribute a body parser from a component

A component can add one or more body parsers via its bindings property:

  1. import {createBodyParserBinding} from '@loopback/rest';
  2. export class XmlComponent implements Component {
  3. bindings = [createBodyParserBinding(XmlBodyParser)];
  4. }

Customize parser options

The request body parser options is bound toRestBindings.REQUEST_BODY_PARSER_OPTIONS. To customize request body parseroptions, you can simply bind a new value to its key.

Built-in parsers retrieve their own options from the request body parseroptions. The parser specific properties override common ones. For example, giventhe following configuration:

  1. {
  2. limit: '1MB'
  3. json: {
  4. strict: false
  5. },
  6. text: {
  7. limit: '2MB'
  8. },
  9. /**
  10. * Validation options for AJV, see https://github.com/epoberezkin/ajv#options
  11. * This setting is global for all request body parsers and it cannot be
  12. * overridden inside parser specific properties such as `json` or `text`.
  13. */
  14. validation: {nullable: true},
  15. }

The json parser will be created with {limit: '1MB', strict: false} and thetext parser with {limit: '2MB'}.

Custom parsers can choose to have its own options from the context bydependency injection, for example:

  1. export class XmlBodyParser implements BodyParser {
  2. name = 'xml';
  3. constructor(
  4. @inject('request.bodyParsers.xml.options', {optional: true})
  5. options: XmlBodyParserOptions = {},
  6. ) {
  7. ...
  8. }
  9. // ...
  10. }

Replace an existing parser

An existing parser can be replaced by binding a different value to theapplication context.

  1. class MyJsonBodyParser implements BodyParser {
  2. // ...
  3. }
  4. app.bodyParser(MyJsonBodyParser, RestBindings.REQUEST_BODY_PARSER_JSON);

Remove an existing parser

An existing parser can be removed from the application by unbinding thecorresponding key. For example, the following code removes the built-in JSONbody parser.

  1. app.unbind(RestBindings.REQUEST_BODY_PARSER_JSON);