How to add custom headers to appsync response?

·

2 min read

So imagine you have direct aws lambda as a resolver. Like in this serverless.yaml file.

https://github.com/R11baka/appsynctemplate/blob/master/serverless.yaml

service: appsync-demo
frameworkVersion: "3"
configValidationMode: "warn"

provider:
  name: aws
  runtime: nodejs18.x
  stage: ${opt:stage, self:custom.defaultStage}
  region: us-west-1
  versionFunctions: true
  logRetentionInDays: 90
  environment:
    AWS_NODEJS_CONNECTION_REUSE_ENABLED: 1

plugins:
  - serverless-appsync-plugin
custom:
  defaultStage: dev

appSync:
  name: appsync-demo-${self:provider.stage}
  schema: 'schema.graphql'
  authentication:
    type: 'API_KEY'
  apiKeys:
    - name: apiKey
      description: dev API key
      expiresAfter: 1M
  dataSources:
    appsyncLambda:
      type: AWS_LAMBDA
      name: appsyncLambda
      config:
        functionName: appsyncLambda
  resolvers:
    query:
      type: Query
      field: hello
      dataSource: appsyncLambda
      kind: UNIT

functions:
  appsyncLambda:
    name: appsyncLambda-${self:provider.stage}
    description: Lambda resolver which accept events from appsync
    timeout: 15
    handler: src/index.handler

So lambda with name appsyncLambda returns JSON to resolver with name query.In the background, we have according to AWS https://docs.aws.amazon.com/appsync/latest/devguide/direct-lambda-reference.html direct lambda resolver. So

As with other data sources, your Lambda function sends a response to AWS AppSync that must be converted to a GraphQL type.

The result of the Lambda function is set on the context object that is available via the Velocity Template Language (VTL) $context.result property.

If the shape of your Lambda function response exactly matches the shape of the GraphQL type, you can forward the response using the following response mapping template:

$util.toJson($context.result)

There are no required fields or shape restrictions that apply to the response mapping template. However, because GraphQL is strongly typed, the resolved mapping template must match the expected GraphQL type.

The main $util.toJson($context.result) if you need to extend headers, you have to replace this default template to your custom template. In serverless.yaml file you have to add an additional parameter response which refers to file response.vtl

 resolvers:
    query:
      type: Query
      field: hello
      dataSource: appsyncLambda
      kind: UNIT
      response: response.vtl

with your custom settings. Where is response.vtl file

#if($ctx.error)
    $util.error($ctx.error.message, $ctx.error.type, $ctx.result)
#end
$util.http.addResponseHeader("Strict-Transport-Security", "max-age=31536000; includeSubDomains")
$util.http.addResponseHeader("Content-Security-Policy", "default-src https:")
$util.toJson($ctx.result)

in one level with serverless.yaml file