How to Get the API Gateway Endpoint in Serverless


I came across the Serverless Framework a while back when I needed a way to abstract away some of the tedious parts of CloudFormation.

Getting a Lambda function behind an API Gateway endpoint could not have been easier, but this isn’t a tutorial for that.

As we know, deploying a Serverless application requires a simple serverless deploy.

This deployment prints out logs that include the API Gateway endpoint our application will eventually make a request to in order to trigger our Lambda function.

I’m using LocalStack here to test my AWS services offline. I’d highly recommend it.

Serverless: Stack update finished...
Service Information
service: localstack-lambda
stage: local
region: us-west-1
stack: localstack-lambda-local
resources: 27
api keys:
  None
endpoints:
  http://localhost:4566/restapis/gnij462kt7/local/_user_request_
functions:
  testGet: localstack-lambda-local-testGet
  testPost: localstack-lambda-local-testPost
layers:
  None

In the example above, we want the endpoint: http://localhost:4566/restapis/gnij462kt7/local/_user_request_.

We can then make requests to this endpoint like so:

# Test GET
curl http://localhost:4566/restapis/gnij462kt7/local/_user_request_/testGet?key1=value1
# Test POST
curl -X POST -H 'Content-type: application/json' \
		--data '{"key1": "value1"}' \
		http://localhost:4566/restapis/gnij462kt7/local/_user_request_/testPost

The tough part comes when we have to manually update the endpoint while developing.

Luckily, we can use some Linux commands to automatically grab that endpoint from the serverless deploy logs.

1. Save serverless deploy logs

First, we want to redirect the output of serverless deploy into a file, which we’ll call deploy_logs.txt.

serverless deploy > deploy_logs.txt

This will hide the output from the terminal, which is less than ideal for developing (we won’t know if there’s an error).

In those cases, we can use tee to print the logs to terminal as well as store them in our log file.

serverless deploy | tee deploy_logs.txt

2. Search for the endpoint in the logs

We can run several commands piped into one another to grab the endpoint from the deploy logs.

cat deploy_logs.txt | grep "endpoints:" -A1 | tail -n 1 | xargs > api_endpoint.txt
  • cat deploy_logs.txt prints the entire log to the terminal.
  • grep "endpoints:" takes the logs and searches for the line with endpoints: in it.
    • -A1 returns the line with endpoints: as well as the following line, which contains the endpoint we want
  • tail -n 1 returns just the last line of the input, which is just our endpoint
  • xargs is a simple way to trim whitespace
  • > api_endpoint.txt stores our endpoint into a text file

At this point, our API Gateway endpoint is sitting inside api_endpoint.txt.

3. Use the endpoint

Finally, we can pull that value from the file and use it to test.

# Test GET
curl `cat api_endpoint.txt`/testGet?key1=value1
# Test POST
curl -X POST -H 'Content-type: application/json' \
		--data '{"key1": "value1"}' \
		`cat api_endpoint.txt`/testPost

cat api_endpoint.txt will simply dump the endpoint in that file into our curl command.

4. Put it inside a Makefile

We can easily put all this into a Makefile task.

deploy:
  serverless deploy | tee deploy_logs.txt
  cat deploy_logs.txt | grep "endpoints:" -A1 | tail -n 1 | xargs > api_endpoint.txt

test:
  curl `cat api_endpoint.txt`/testGet?key1=value1
  curl -X POST -H 'Content-type: application/json' \
      --data '{"key1": "value1"}' \
      `cat api_endpoint.txt`/testPost