Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to send query request from AWS Lambda with Serverless Framework to AppSync GraphQL API?

I've been having this problem of understanding how to, in simplest way possible,send, by using AWS Lambda, query request over to a certain AppSync GraphQL API ( which has API KEY auth mode).

I'm sort of a beginner, hence I've been reading a lot, in search of useful tips and tutorials that might explain this, the closest I came to a solution is this tutorial: https://docs.aws.amazon.com/appsync/latest/devguide/building-a-client-app-node.html, which suggests using Apollo Client. My first question is, is this the best approach to my goal (using Apollo Client + AWS Lambda to send query,mutations to AppSync GraphQL API)? If not, what would be the best practice/way to do so?

Here's my current code based of the above mentioned tutorial:

const gql  = require('graphql-tag');
const AWSAppSyncClient = require('aws-appsync').default;
const AUTH_TYPE = require('aws-appsync-auth-link/lib/auth-link').AUTH_TYPE;
require('es6-promise').polyfill();
require('isomorphic-fetch');


module.exports.handler =  async function(event, context) {

    //console.log("before_client_setup");

    const client = new AWSAppSyncClient({
      url: '******',
      region: '******',
      auth: {
        type: AUTH_TYPE.API_KEY,
        apiKey:'******'
      },
      disableOffline: true
    });

    //console.log("before_gql_query");

    const query = gql`
      query listJobs {
        listJobs{
          items {
            id title employer datePosted location url
          }
        }
      }
    `;

   //console.log("before_client_call");

    client.hydrated().then(function (client) {
      //Now run a query

      //console.log("before_client_query");

        client.query({ query: query, fetchPolicy: 'network-only' })   //Uncomment for AWS Lambda
          .then(function logData(data) {
              console.log('results of query: ', data);
          })
          .catch(console.error);
    });
}

url, region, auth parameters are hard-coded just to test if it works (I know that it's not a best practice), but when I invoke this function trough serverless framework with the command:sls invoke -f streamFunction --stage stg the result I get inside of console is: null

Expected result (which I got when using Postman and passing correct url and api key): https://i.sstatic.net/gAfRL.png

CloudWatch Logs aren't of any help either, as they are not giving useful insight into what the problem may be. Here's a screenshot of them upon being invoked:

https://i.sstatic.net/WKXsP.png

Any advices?

like image 366
Goran Cabarkapa Avatar asked Dec 05 '25 00:12

Goran Cabarkapa


1 Answers

Ok, so I think the main problem was because I was using this syntax:

client.hydrated().then(function (client) {

      client.query({ query: query, fetchPolicy: 'network-only' })   //Uncomment for AWS Lambda
      .then(function logData(data) {
          console.log('results of query: ', data);
      })
      .catch(console.error);
});

inside of async function which is my lambda. Instead, await keyword should be used. Here's the whole code which solved the problem:

const gql = require('graphql-tag');
const AWSAppSyncClient = require('aws-appsync').default;
const AUTH_TYPE = require('aws-appsync-auth-link/lib/auth-link').AUTH_TYPE;
require('es6-promise').polyfill();
require('isomorphic-fetch');
module.exports.handler = async function (event, context) {
  try {
    const appSyncClient = new AWSAppSyncClient(
      {
        url: '******',
        region: '******',
        auth: {
          type: AUTH_TYPE.API_KEY,
          apiKey: '******'
        },
        disableOffline: true
      },
      {
        defaultOptions: {
          query: {
            fetchPolicy: 'network-only',
            errorPolicy: 'all',
          },
        },
      }
    );  
    const query = await gql`
      query listJobs {
        listJobs{
          items {
            id title employer datePosted location url
          }
        }
      }
    `;
    const client = await appSyncClient.hydrated();
    const data =   await client.query({query});
    console.log(data);

  } catch (error) {
    return context.fail(error);
  }
  return context.succeed("success");
}

And here are the logs from CloudWatch: https://i.sstatic.net/O6AcB.png

Hope this helps :)

like image 62
Goran Cabarkapa Avatar answered Dec 07 '25 14:12

Goran Cabarkapa