Search code examples
javascriptnode.jstypescriptloopbackjsloopback4

What is the best practice of creating requestBody in loopback 4?


Currently I am working on Loopback4 and I had this issue.

    @requestBody({
      content: {
        'application/json': {
          schema: getModelSchemaRef(LoginCredentials, {
            title: 'Login'
          })
        },
      }
    }) credentials: LoginCredentials

In this code block, I created a model for request body. Is this the best way to define request body?


Solution

  • Is this the best way to define request body?

    Yes. Models' main purpose is to be the main interface for defining the shape of any data. This enables re-use across different layers (such as REST and Repository), and encourages creating a single source of truth. This means better long-term code maintainability as issues such as data design drift and repeated code.

    Are there other ways to define a request body?

    Yes. the request body decoration (@requestBody()) accepts OpenAPI 3.0 Specification objects. Hence, it is possible to write the OpenAPI spec instead of relying on getModelSchemaRef() to generate it from a Model. However, this should be done sparingly to mitigate the aforementioned issues.

    What if I have too many models?

    Artifacts that are booted can be stored in nested directories; Hence, models can be segregated by their business domains. For example, models relating to authentication can be stored under src/models/auth/MyModel.model.ts.

    Code segregation beyond models

    Another solution is to separate the code using components. If done right, components allow near-complete segregation of code by hiding the bootstrapping logic and artifacts from the main codebase. For example, all authentication code and artifacts - notwithstanding controllers, datasources and models - can be kept under src/components/auth/*. From the perspective of the rest of the application, the only action needed is to bind the component using app.component(MyAuthComponent) and maybe some binding configuration. This means there's a clear separation of responsibility, thereby improving code readability as developers will not have to see the implementation details of the segregated code unless necessary.