1

I'm new with loopback 4 and I really have difficulty with the documentation that is some time not up to date. I succeed to add an authentification system and a route to log in to the users. My problem is on the "/explorer" URL, I don't know how can I add example value on the request body schema of a custom route.

There is my route:

@post('/users/login', {
    responses: {
      '200': {
        description: 'Token',
        content: {
          'application/json': {
            schema: {
              type: 'object',
              properties: {
                token: {
                  type: 'string'
                }
              }
            }
          }
        }
      }
    }
  })
  async login(
    @requestBody() credentials: Credentials,
  ): Promise<{token: string}> {
    // make sure user exist,password should be valid
    const user = await this.userService.verifyCredentials(credentials);
    // console.log(user);
    const userProfile = await this.userService.convertToUserProfile(user);
    // console.log(userProfile);

    const token = await this.jwtService.generateToken(userProfile);
    return Promise.resolve({token: token})
  }

And I wish to add:

{
   "username": "string",
   "password": "string"
}

Here: /explorer url

I suppose that there is a simple way to do it but I really can't find anything about it.

Madaky
  • 389
  • 1
  • 9
Mathias Osterhagen
  • 402
  • 1
  • 3
  • 19

2 Answers2

1

FYI: The loopback4 uses the route Decorator, which provides OpenAPI specification to describe the endpoint. There is en-detailed about OpenAPI decorator in loopbac4 here.
Now to solve the above issue. lets create:

  1. Schema for User Login i.e {"username":string, "password":string} in the schema definition you can also add the validation rules.

    const  UserLoginSchema = {
    type: 'object',
    required: ['email', 'password'],
    properties: {
      username: {
        type: 'string',
      },
      password: {
        type: 'string',
      },
    },
    }; ```
    
  2. Now lets quickly create your RequestBody c'tor for login. Remember as per OpenApi Specification the request body would contain description, required and content.

 export const UserLoginRequestBody = {
      description: 'Required input for login',
      required: true,
      content: {
        'application/json': {schema: UserLoginSchema},
      },
    };
  1. Now you are ready to use your request body.
  async login(
    @requestBody(UserLoginRequestBody) credentials: Credentials,
  ): Promise<{token: string}> {
..restCode

Thats get you done.

Madaky
  • 389
  • 1
  • 9
1

Thank you @Madaky. After reading your answer I just directly added the differents object directly in my route to not make extras files (i don't know if its a good practice) but it works.

There is the final code with the information added inside the "@requestBody" function:


  @post('/users/login', {
    responses: {
      '200': {
        description: 'Token',
        content: {
          'application/json': {
            schema: {
              type: 'object',
              properties: {
                token: {
                  type: 'string'
                }
              }
            }
          }
        }
      }
    }
  })
  async login(
    //here above inside @requestBody
    @requestBody(
      {
        description: 'Required input for login',
        required: true,
        content: {
          'application/json': {
            schema: {
              type: 'object',
              required: ['email', 'password'],
              properties: {
                username: {
                  type: 'string',
                },
                password: {
                  type: 'string',
                },
              },
            },
          }
        },
      }
    ) credentials: Credentials,
  ): Promise<{token: string}> {
    // make sure user exist,password should be valid
    const user = await this.userService.verifyCredentials(credentials);
    // console.log(user);
    const userProfile = await this.userService.convertToUserProfile(user);
    // console.log(userProfile);

    const token = await this.jwtService.generateToken(userProfile);
    return Promise.resolve({token: token})
  }

It's working like a charm, thank you!

Mathias Osterhagen
  • 402
  • 1
  • 3
  • 19
  • Good to Hear. Carry on. To make the work isolated you can use the code in different files. which are easier to track for later revisions – Madaky May 29 '20 at 16:40