amazon-web-servicesaws-lambdaaws-api-gatewayaws-samaws-http-api

AWS API Gateway HTTP API Not Returning application/json content-type


I am using AWS SAM to build a lambda-based API. Originally I used a "Rest API" but I have converted my Rest API over to a HTTP API but the content type returned from the API is now "text/plain" instead of "application/json".

Any ideas why my API is returning text/plain instead of application/json? My understanding was that HTTP API should be returning application/json by default. Is there a way to change it? Most of the docs I've read focus on changing the content type of a Rest API, not an HTTP API.

My template.yaml looks like this:

Resources:

  ApiGatewayApi:
    Type: AWS::Serverless::HttpApi
    Properties:
      StageName: Prod
  UsersFunctionGet:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: UsersFunctionGet
      CodeUri: function-users/
      Handler: src/handlers/users-get.handler
      Runtime: nodejs18.x
      Architectures:
        - x86_64
      Events:
        UsersEvent:
          Type: HttpApi
          Properties:
            Path: /
            Method: get
            ApiId: !Ref ApiGatewayApi
        UserEvent:
          Type: HttpApi
          Properties:
            Path: /{user_id}
            Method: get
            ApiId: !Ref ApiGatewayApi
      Policies:
        - DynamoDBCrudPolicy:
            TableName: !Ref UsersTable
      Environment:
        Variables:
          USERS_TABLE: !Ref UsersTable
      FunctionUrlConfig:
        AuthType: NONE # AWS_IAM
    Metadata:
      BuildMethod: esbuild
      BuildProperties:
        Minify: true
        Target: es2020
        Sourcemap: true
        EntryPoints:
          - src/handlers/users-get.ts
  APIMapping:
    Type: AWS::ApiGatewayV2::ApiMapping
    Properties:
      ApiMappingKey: 'users'
      ApiId: !Ref ApiGatewayApi
      Stage: !Ref ApiGatewayApi.Stage

I had expected the default payload response to be application/json but it's not for some reason.


Solution

  • You can set the content-type by your return value in the Lambda function.

    For payloadFormatVersion 1.0, you need to include content-type header in the response:

    {
        "body": "Lambda reponse",
        "isBase64Encoded": false,
        "statusCode": 200,
        "headers": { "content-type": "application/json", ... }
    }   
    

    For payloadFormatVersion 2.0:

    With the 2.0 format version, API Gateway can infer the response format for you. API Gateway makes the following assumptions if your Lambda function returns valid JSON and doesn't return a statusCode.

    isBase64Encoded is false.

    statusCode is 200. content-type is application/json.

    body is the function's response.

    See: Working with AWS Lambda proxy integrations for HTTP APIs