Is there a way to change the http status codes ret

2019-01-03 01:48发布

For instance if I want to return a specific 400 error for invalid parameters or perhaps a 201 when the lambda function call resulted in a create.

I'd like to have different http status codes but it looks like api gateway always returns a 200 status code even if the lambda function is returning an error.

9条回答
▲ chillily
2楼-- · 2019-01-03 02:21

To be able to return a custom error object as JSON you have to jump through a couple of hoops.

First, you must fail the Lambda and pass it a stringified JSON object:

exports.handler = function(event, context) {
    var response = {
        status: 400,
        errors: [
            {
              code:   "123",
              source: "/data/attributes/first-name",
              message:  "Value is too short",
              detail: "First name must contain at least three characters."
            },
            {
              code:   "225",
              source: "/data/attributes/password",
              message: "Passwords must contain a letter, number, and punctuation character.",
              detail: "The password provided is missing a punctuation character."
            },
            {
              code:   "226",
              source: "/data/attributes/password",
              message: "Password and password confirmation do not match."
            }
        ]
    }

    context.fail(JSON.stringify(response));
};

Next, you setup the regex mapping for each of the status codes you would like to return. Using the object I defined above you would setup this regex for 400:

.*"status":400.*

Finally, you setup a Mapping Template to extract the JSON response from the errorMessage property returned by Lambda. The Mapping Template looks like this:

$input.path('$.errorMessage')

I wrote an article on this that goes into more detail and explains the response flow from Lambda to API Gateway here: http://kennbrodhagen.net/2016/03/09/how-to-return-a-custom-error-object-and-status-code-from-api-gateway-with-lambda/

查看更多
Root(大扎)
3楼-- · 2019-01-03 02:23

Update per 20-9-2016

Amazon finally made this easy using the Lambda Proxy integration. This allows your Lambda function to return proper HTTP codes and headers:

let response = {
    statusCode: '400',
    body: JSON.stringify({ error: 'you messed up!' }),
    headers: {
        'Content-Type': 'application/json',
    }
};

context.succeed(response);

Say goodbye request/response mapping in the API Gateway!

Option 2

Integrate an existing Express app with Lambda/API Gateway using aws-serverless-express.

查看更多
萌系小妹纸
4楼-- · 2019-01-03 02:30

The easiest way to do this is to use LAMBDA_PROXY integration. Using this method, you don't need any special transformations to be set into API Gateway pipeline.

Your return object would have to be similar to the snippet below:

module.exports.lambdaHandler = (event, context, done) => {
    // ...
    let response = {
        statusCode: 200, // or any other HTTP code
        headers: {       // optional
             "any-http-header" : "my custom header value"
        },
        body: JSON.stringify(payload) // data returned by the API Gateway endpoint
    };
    done(null, response); // always return as a success
};

It does have a few drawbacks: as having to be specially careful about error handling, and coupling your lambda function to the API Gateway endpoint; that said, if you were not really going to use it anywhere else, it is not that much of a problem.

查看更多
祖国的老花朵
5楼-- · 2019-01-03 02:32

I'm using serverless 0.5. This is how it works, for my case

s-function.json:

{
  "name": "temp-err-test",
  "description": "Deployed",
  "runtime": "nodejs4.3",
  "handler": "path/to/handler.handler",
  "timeout": 6,
  "memorySize": 1024,
  "endpoints": [
    {
      "path": "test-error-handling",
      "method": "GET",
      "type": "AWS_PROXY",
      "responses": {
        "default": {
          "statusCode": "200"
        }
      }
    }
  ]
}

handler.js:

'use strict';
function serveRequest(event, context, cb) {
  let response = {
    statusCode: '400',
    body: JSON.stringify({ event, context }),
    headers: {
      'Content-Type': 'application/json',
    }
  };
  cb(null, response);
}
module.exports.handler = serveRequest;
查看更多
再贱就再见
6楼-- · 2019-01-03 02:38

This is how it's recommended on an AWS Compute Blog if using API Gateway. Checking to see if integration works with direct Lambda invocation.

var myErrorObj = {
    errorType : "InternalServerError",
    httpStatus : 500,
    requestId : context.awsRequestId,
    message : "An unknown error has occurred. Please try again."
}
callback(JSON.stringify(myErrorObj));

For direct Lambda invocations, this appears to be the best solution parsing on the client-side.

查看更多
Summer. ? 凉城
7楼-- · 2019-01-03 02:40

Here's the fastest way to return custom HTTP Status Codes and a custom errorMessage:

In the API Gateway dashboard, do the following:

  1. In the method for your resource, click on method response
  2. In the HTTP Status table, click add response and add in each HTTP Status Code you would like to use.
  3. In the method for your resource, click on integration response
  4. Add an integration response for each of the HTTP Status Codes you created earlier. Make sure input passthrough is checked. Use lambda error regex to identify which status code should be used when you return an error message from your lambda function. For example:

    // Return An Error Message String In Your Lambda Function
    
    return context.fail('Bad Request: You submitted invalid input');
    
    // Here is what a Lambda Error Regex should look like.
    // Be sure to include the period and the asterisk so any text
    // after your regex is mapped to that specific HTTP Status Code
    
    Bad Request: .*
    
  5. Your API Gateway route should return this:

    HTTP Status Code: 400
    JSON Error Response: 
        {
            errorMessage: "Bad Request: You submitted invalid input"
        }
    
  6. I see no way to copy these settings and re-use it for different methods, so we have much annoying redundant manual inputting to do!

My Integration Responses look like this:

aws api gateway lambda error response handling

查看更多
登录 后发表回答