Add a Controller

soap-calculator-add-service

Now it is time to add the controller which will make the REST endpointsavailable to client applications through the REST server.

Scaffold a BASIC controller

Run the following command to create a BASIC controller.

  1. lb4 controller calculator

Next, select the Empty Controller.

  1. Controller Calculator will be created in src/controllers/calculator.controller.ts
  2. ? What kind of controller would you like to generate? (Use arrow keys)
  3. Empty Controller
  4. REST Controller with CRUD functions

At this point, you should have two files in the src/controllers directory.

  • calculator.controller.ts
  • index.tsThe generated Empty controller looks like this. You may remove the comments atthis point.
  1. // Uncomment these imports to begin using these cool features!
  2. // import {inject} from '@loopback/context';
  3. export class CalculatorController {
  4. constructor() {}
  5. }

Adding the imports into the Controller

Add the following two lines at the begining of thesrc/controllers/calculator.controller.ts file.

The get and param are classes imported from the LB4 REST server andused to make the @get and @param decorators available.

The HttpErrors is used to help use raise the precondition error whenever wefind that the client application is trying to divide by zero.

  1. import {inject} from '@loopback/core';
  2. import {get, param, HttpErrors} from '@loopback/rest';

To complete importing the necessary classes, we need to also include the serviceand the interfaces we modeled in the previous step as follows:

  1. import {
  2. CalculatorService,
  3. CalculatorParameters,
  4. AddResponse,
  5. MultiplyResponse,
  6. DivideResponse,
  7. SubtractResponse,
  8. } from '../services/calculator.service';

Injecting the Service into the Controller

In the constructor method, we inject the service. Please note that the keyservices.CalculatorService has not been defined so far, we will inform ourApplication about this key in the last step.

  1. export class CalculatorController {
  2. constructor(
  3. @inject('services.CalculatorService')
  4. protected calculatorService: CalculatorService,
  5. ) {}
  6. }

Creating the end point methods

Now we need to create an endpoint for each operation. There will be four (4)endpoints in total. Each endpoint is a method inside the CalculatorController,so make sure the next code segments are placed before the last } in the file.

Adding the Divide end point

Our divide method looks like this initially. Notice we are using the<CalculatorParameters> for type assertion. The Node.js methods defined in theservice are available from here due to the dependency injection availablethrough LB4.

  1. async divide(intA: number, intB: number): Promise<DivideResponse> {
  2. //Preconditions
  3. if (intB === 0) {
  4. throw new HttpErrors.PreconditionFailed('Cannot divide by zero');
  5. }
  6. return this.calculatorService.divide(<CalculatorParameters>{
  7. intA,
  8. intB,
  9. });
  10. }

Now, if we add the @GET decorator we are making it available to the RESTserver as follows.

  1. @get('/divide/{intA}/{intB}')
  2. async divide(intA: number, intB: number): Promise<DivideResponse> {

Finally we can use the @param decorator on the two properties to help usvalidate the data type associated to each parameter. In this case we are makingsure the client application only sends integer values as the remote SOAP webservice expects this data type and this is done automatically for us.

The final code looks like as follows:

  1. @get('/divide/{intA}/{intB}')
  2. async divide(
  3. @param.path.integer('intA') intA: number,
  4. @param.path.integer('intB') intB: number,
  5. ): Promise<DivideResponse> {
  6. //Preconditions
  7. if (intB === 0) {
  8. throw new HttpErrors.PreconditionFailed('Cannot divide by zero');
  9. }
  10. return this.calculatorService.divide(<CalculatorParameters>{
  11. intA,
  12. intB,
  13. });
  14. }
Adding the remaining end points

Add the following end point methods inside the CalculatorController class abovethe divide end point method.

  1. @get('/multiply/{intA}/{intB}')
  2. async multiply(
  3. @param.path.integer('intA') intA: number,
  4. @param.path.integer('intB') intB: number,
  5. ): Promise<MultiplyResponse> {
  6. return this.calculatorService.multiply(<CalculatorParameters>{
  7. intA,
  8. intB,
  9. });
  10. }
  11. @get('/add/{intA}/{intB}')
  12. async add(
  13. @param.path.integer('intA') intA: number,
  14. @param.path.integer('intB') intB: number,
  15. ): Promise<AddResponse> {
  16. return this.calculatorService.add(<CalculatorParameters>{
  17. intA,
  18. intB,
  19. });
  20. }
  21. @get('/subtract/{intA}/{intB}')
  22. async subtract(
  23. @param.path.integer('intA') intA: number,
  24. @param.path.integer('intB') intB: number,
  25. ): Promise<SubtractResponse> {
  26. return this.calculatorService.subtract(<CalculatorParameters>{
  27. intA,
  28. intB,
  29. });
  30. }

Navigation

Previous step: Add a Service

Next step:Run and Test the Application