Now that we have our backend completely set up and secured, let’s test the API we just deployed.

To be able to hit our API endpoints securely, we need to follow these steps.

  1. Authenticate against our User Pool and acquire a user token.
  2. With the user token get temporary IAM credentials from our Identity Pool.
  3. Use the IAM credentials to sign our API request with Signature Version 4.

These steps can be a bit tricky to do by hand. So we created a simple tool called AWS API Gateway Test CLI.

You can install it by running the following.

$ npm install -g aws-api-gateway-cli-test

We need to pass in quite a bit of our info to complete the above steps.

And run the following.

apig-test \
--username='admin@example.com' \
--password='Passw0rd!' \
--user-pool-id='YOUR_COGNITO_USER_POOL_ID' \
--app-client-id='YOUR_COGNITO_APP_CLIENT_ID' \
--cognito-region='YOUR_COGNITO_REGION' \
--identity-pool-id='YOUR_IDENTITY_POOL_ID' \
--invoke-url='YOUR_API_GATEWAY_URL' \
--api-gateway-region='YOUR_API_GATEWAY_REGION' \
--path-template='/notes' \
--method='POST' \
--body='{"content":"hello world","attachment":"hello.jpg"}'

While this might look intimidating, just keep in mind that behind the scenes all we are doing is generating some security headers before making a basic HTTP request. You’ll see more of this process when we connect our React.js app to our API backend.

If the command is successful, the response will look similar to this.

Authenticating with User Pool
Getting temporary credentials
Making API request
{ status: 200,
  statusText: 'OK',
  data: 
   { userId: 'us-east-1:9bdc031d-ee9e-4ffa-9a2d-123456789',
     noteId: '8f7da030-650b-11e7-a661-123456789',
     content: 'hello world',
     attachment: 'hello.jpg',
     createdAt: 1499648598452 } }

And that’s it for the backend! Next we are going to move on to creating the frontend of our app.


Common Issues

  • Response {status: false}

    If your apig-test command fails with the {status: false} response; we can do a few things to debug this. This response is generated by our handler functions when there is an error. Add a console.log like so in your handler function.

    catch(e) {
      console.log(e);
      callback(null, failure({status: false}));
    }
    

    And deploy it using serverless deploy. But we can’t see this output when we make an HTTP request to it, since the console logs are not sent in our HTTP responses. We need to check the logs to see this. Head over to your AWS Console > CloudWatch > click Logs in the sidebar > select the Log Group named /aws/lambda/notes-app-api-prod-create > and expand the events. This should give you an idea of the error and help you debug it.

    A common source of errors here is an improperly indented serverless.yml. Make sure to double-check the indenting in your serverless.yml to the one from this chapter.