Calling an AWS AppSync API from a Lambda Function Using Node.js Fetch

2023-03-21

#cloud#backend
Calling an AWS AppSync API from a Lambda Function Using Node.js Fetch

You need a Lambda to talk to AppSync. You start searching for an SDK wrapper, a special client, some AppSync-specific library. You overcomplicate it before writing a single line of code.

Here's the thing most developers miss: a GraphQL API is just a REST API with a single endpoint and a POST body. That's it. Once you see it that way, calling AppSync from Lambda becomes trivially simple.

GraphQL Is Just a POST

REST gives you many endpoints. GraphQL gives you one. The difference is in the payload, not the protocol.

// REST API: GET request to fetch user data
fetch('https://api.example.com/users/1');

// GraphQL API: POST request to fetch user data
fetch('https://api.example.com/graphql', {
  method: 'POST',
  body: JSON.stringify({
    query: `
      query {
        user(id: 1) {
          id
          name
          email
        }
      }
    `
  })
});

The Simple Way: fetch

No special library needed. Install node-fetch, construct the POST, send it.

npm install node-fetch
const fetch = require('node-fetch');

exports.handler = async (event) => {
  const apiUrl = 'https://yourappsyncapi.appsync-api.us-east-1.amazonaws.com/graphql';
  const apiKey = 'your-appsync-api-key';

  const query = `
    query {
      listTodos {
        items {
          id
          name
          completed
        }
      }
    }
  `;

  const response = await fetch(apiUrl, {
    method: 'POST',
    headers: {
      'x-api-key': apiKey,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ query })
  });

  const data = await response.json();
  return data;
};

That's the entire Lambda. A POST request with a query string and an API key header. Nothing magical about it.

The AWS SDK Way

If you prefer staying inside the AWS ecosystem, the SDK provides an AppSync client:

const AWS = require('aws-sdk');
AWS.config.update({ region: 'us-east-1' });

const appsync = new AWS.AppSync({ apiVersion: '2017-07-25' });
const apiKey = 'your-appsync-api-key';

exports.handler = async (event) => {
  const params = {
    apiId: 'your-appsync-api-id',
    query: `
      query {
        listTodos {
          items {
            id
            name
            completed
          }
        }
      }
    `,
    apiKey
  };

  try {
    const data = await appsync.startQueryExecution(params).promise();
    return data;
  } catch (error) {
    console.error('Error executing query:', error);
    throw new Error('Query execution failed');
  }
};

Which One?

  • Fetch: More control over the HTTP layer. Works across AWS accounts where IAM permissions are messy. Fewer abstractions to debug.

  • AWS SDK: More integrated, easier to maintain if you're already deep in AWS tooling. Abstracts away HTTP details you might want to see.

I reach for fetch almost every time. It's one less abstraction between me and the API, and when something breaks at 2 AM, I want to see the raw HTTP request — not debug an SDK wrapper around a wrapper.

The next time you need a Lambda to call AppSync, skip the research rabbit hole. It's a POST request. Treat it like one.