Trying to fetch response from Goodreads API

Great! Could you show an example in code of how that replaces an expressjs backend?

Sorry for the late reply, yes ill try to add an example in on weekends :slight_smile:

I’ll talk about the AWS lambda functions because all the other functions providers (Google, Salesforce) will employ a similar process.
I took a reference from your repository JacksonBate/example-goodreads-api-relay for app.js, the below code is just like writing a node module.

let responseHeaders = {
    "Access-Control-Allow-Origin": `http://${process.env.APP_DOMAIN}`,
    "Access-Control-Allow-Credentials": true,
};

exports.functionFoo = async (event, context) => {
    try {
        // This uses string interpolation to make our search query string
        // it pulls the posted query param and reformats it for goodreads
        const searchString = `q=${event.queryStringParameters.q}`;

        // It uses node-fetch to call the goodreads api, and reads the key from .env
        const response = await fetch(
            `https://www.goodreads.com/search/index.xml?key=${process.env.GOODREADS_API_KEY}&${searchString}`,
        );
        //more info here https://www.goodreads.com/api/index#search.books
        const xml = await response.text();

        // Goodreads API returns XML, so to use it easily on the front end, we can
        // convert that to JSON:
        const json = convert.xml2json(xml, { compact: true, spaces: 2 });

        // The API returns stuff we don't care about, so we may as well strip out
        // everything except the results:
        const results = JSON.parse(json).GoodreadsResponse.search.results;


        return {
            "statusCode": 200,
            "headers": responseHeaders,
            "body": results,
            "isBase64Encoded": false
        };
    } catch (err) {
        return {
            "statusCode": 500,
            "headers": responseHeaders,
            "body": err.message,
            "isBase64Encoded": false
        };
    }
}

A few points to note here are, the query params or body params passed while calling the lambda function URL are to be taken from argument event (similar to the request in express). The lambda functions should return the response in a specific format or else it fails. CORS needs to be enabled in your case as its a different domain application. For this, I would recommend using the serverless framework and for CORS refer https://serverless.com/blog/cors-api-gateway-survival-guide/ for deployment.

An example of serverless.yml

service: your-app-name
provider:
  name: aws
  runtime: nodejs10.x
  stage: dev
  environment:
    NODE_PATH: "./:/opt/node_modules"
functions:
  functionFoo:
    handler: handler.functionFoo 
    events:
     - http:
         path: foo
         method: get
         cors: true

The lambda functions are called using a url generated using api gateway in AWS lambda (https://docs.aws.amazon.com/apigateway/latest/developerguide/getting-started-with-lambda-integration.html). But if you use the serverless framework, everything would be easier. a bit of a learning curve but definately worth it.

Thanks for following up. I look forward to trying this out when I get a chance :slight_smile:

yes sure, let me know if you need any help.

Just wanted to share my post for quickly getting started with functions and serverless framework, https://medium.com/@badgamerbad/quickly-get-started-with-serverless-framework-sls-for-aws-lambda-function-layers-and-debug-them-39a107c814f6

2 Likes