API Gateway - is an application server that receives user queries, analogues are apache or httpd and nginx.

Lambda is the server scripts, something like *.php files in old good LAMP stack.

Two types of lambda integrations to APIGateway:

  • Lambda proxy - request and response are generated in lambda
  • Lambda - request and response are pre-processed in APIGateway, lambda is used as pure function
NOTE: Serverless automatically creates APIGateways depending on your lambda configuration.

Lambda proxy integration

Example success scenario:

module.exports.hello = (event, context, callback) => {
  const response = {
    statusCode: 200,
    headers: {
      "x-custom-header" : "my custom header value"
    },
    body: JSON.stringify({
      message: 'Go Serverless v1.0! Your function executed successfully!',
      input: event,
    }),
  };

  // success response
  callback(null, response);
};

Example fail scenario:

module.exports.hello = (event, context, callback) => {
  const errorResponse = {
    statusCode: 400,
    headers: {
      "x-custom-header" : "my custom header value"
    },
    body: JSON.stringify({
      message: 'Bad request Dude',
    }),
  };

  // Do not use callback(new error(errorResponse)) in lambda-proxy
  // error response
  callback(null, errorResponse);
};

Serverless yaml:

functions:
  hello:
    handler: handler.hello
    events:
      - http:
          path: hello
          method: get

Lambda integration

Pure lambda integration - is when `APIGateway` controls all input and output and uses lambda for isolated processing.

CLIENT -> method.request ->integration.request -> LAMBDA-> integration.response ->method.response-> CLIENT

Templates are written in Apache Velocity Template Language an JSONPath.

Sample pure lambda

module.exports.hello = (event, context, callback) => {
  const { someId } = event;

  const response = {
    customHeaders: {
      "x-custom-header" : "my custom header value"
    },
    customBody: JSON.stringify({
      message: `Some id passed: ${someId}`,
      input: event,
    }),
  };

  // success response
  callback(null, response);
};

Sample serverless.yaml that uses variables returned from lambda:

functions:
  hello:
    handler: handler.hello
    events:
    - http:
        path: hello/{someId}
        method: get
        integration: lambda
        request:
          parameters:
            path:
              someId: true
          template:
            application/json: >
              {
                "assetId": "$input.params('someId')"
              }
        response:
          headers:
            Content-Type: "'text/plain'"
            custom: integration.response.body.customHeaders['x-custom-header']
          template: $input.path("$.customBody")