Page Contents
To get started with accessing REST APIs, you need to create a datasource asdiscussed below:
Add a Datasource with OpenAPI specification
When calling REST services which comes with the OpenAPI specification, selectOpenAPI
for connector. The OpenAPI connector will beused.
$ lb4 datasource? Datasource name: ds? Select the connector for ds: OpenAPI (supported by StrongLoop)? HTTP URL/path to Swagger spec file (file name extension .yaml/.yml or .json):petstore.json? Validate spec against Swagger spec 2.0?: No? Security config for making authenticated requests to API:? Use positional parameters instead of named parameters?: No create src/datasources/ds.datasource.ts
For details regarding the prompts about authentication and positionalparameters, see the Authentication andNamed parameters vs positional parameterssections of the OpenAPI connector page.
Note:
Make sure the url
in the servers
property in the OpenAPI specification is an absolute path. If you cannot change the specification, you can save the OpenAPI spec and just modify the url
value before creating a DataSource associated with it.
Datasource for REST service without OpenAPI specification
In the case where the REST services do not have a corresponding OpenAPIspecification, select REST services
for connector. We’ll leave the default forthe last 3 prompts.
$ lb4 datasource? Datasource name: restds? Select the connector for restds: REST services (supported by StrongLoop)? Base URL for the REST service: https://swapi.dev/api/? Default options for the request:? An array of operation templates:? Use default CRUD mapping: No
The next step is to edit the DataSource file for options
and operations
.
The REST connector uses therequest module as the HTTP client. Youcan configure the same options as for the request()
function. See details inthis documentation page.
The template
object specifies the REST API invocation as a JSON template. Youcan find more details in theDefining a custom method using a template page.
const config = { name: 'restds', connector: 'rest', baseURL: 'https://swapi.dev/api/', crud: false, options: { headers: { accept: 'application/json', 'content-type': 'application/json', }, }, operations: [ { template: { method: 'GET', url: 'https://swapi.dev/api/people/{personId}', }, functions: { getCharacter: ['personId'], }, }, ],};
Add a service
Add a service using the Service generator and specifythe DataSource that you just created.
Define the methods that map to the operations
In the Service interface, define the methods that map to the operations of yourexternal service.
To promote type safety, we recommend you to declare data types and serviceinterfaces in TypeScript and use them to access the service proxy.
export interface PeopleService { getCharacter(personId: number): Promise<object>;}
Alternately, we also provide a weakly-typed generic service interface asfollows:
/** * A generic service interface with any number of methods that return a promise */export interface GenericService { [methodName: string]: (...args: any[]) => Promise<any>;}
For details on implementing the Services with OpenAPI DataSource, see theOpenAPI connector page.
Add a Controller
Add a controller using the Controller generator withthe Empty Controller
option.
Inject the Service in the constructor
constructor( @inject('services.PeopleService') protected peopleService: PeopleService, ) {}
Add the REST endpoints
This will be similar to how you normally add a REST endpoint in a Controller.The only difference is you’ll be calling the methods that you’ve exposed in theService interface.
@get('/people/{personId}') async getCharacter( @param.path.integer('personId') personId: number, ): Promise<object> { //Preconditions return this.peopleService.getCharacter(personId); }
@post('/people') async getPeople( @param.query.string('name') name: string, ): Promise<object> { //Preconditions return this.peopleService.getPeople(name); }
For calling Services with OpenAPI DataSource,
- the parameters need to be wrapped in a JSON object
- the response includes the headers and the body
See the code snippet below for illustration:
@get('/pets/{petId}', { responses: { '200': { description: 'Pet model instance', content: {'application/json': {schema: PetSchema}}, }, }, }) async findPetById(@param.path.number('petId') petId: number): Promise<Pet> { // wrap the parameters in a JSON object const response = await this.petStoreService.getPetById({petId: petId}); // we normally only return the response body return response.body; }}
More examples
- REST service tutorial:https://loopback.io/doc/en/lb4/todo-tutorial-geocoding-service.html