Creating business logic on Amplify
Tags: aws, amplify, node
Published: 2020-12-09 07:53:07

As described in [this document](https://aws.amazon.com/blogs/mobile/appsync-microservices/), GraphQL on AppSync can connect many data sources as business logic. For example, API Gateway, another AppSync, and Fargate via HTTP and lambda function.

I think, for a small project, the lambda function as a data source is useful for writing business logic.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/6vn5zcdyckta7x34clvn.png)

We have two approaches to get data. A lambda function gets data from DynamoDB and GraphQL.

# Create a lambda function

See also, https://docs.amplify.aws/guides/functions/dynamodb-from-js-lambda/q/platform/js.

```
$ amplify add function
```

Amplify function needs permission to read/write to DynamoDB and GraphQL

```
$ amplify update function

? Do you want to update the Lambda function permissions to access other resources in this project? Yes
? Select the category api, storage
Api category has a resource called amplifynuxt
? Select the operations you want to permit for amplifynuxt create, read, update, delete
Storage category has a resource called <Your DynamoDB table>:@model(appsync)
? Select the operations you want to permit for <Your DynamoDB table>:@model(appsync) create, read, update, delete
...

You can access the following resource attributes as environment variables from your Lambda function
        API_<Your API name>_GRAPHQLAPIENDPOINTOUTPUT
        API_<Your API name>_GRAPHQLAPIIDOUTPUT
        API_<Your API name>_GRAPHQLAPIKEYOUTPUT
        API_<Your API name>_PROPERTYTABLE_ARN
        API_<Your API name>_PROPERTYTABLE_NAME
```

Add a query in _schema.graphql_

**schema.graphql**
```
type Query {
  getData(msg: String): String @function(name: "<your lambda function name>-${env}")
}
```

## Gets data from DynamoDB

In your _index.js_ in _amplify/backend/function/\<your lambda function name\>/src_, change code like blow.

```
const AWS = require('aws-sdk');
const docClient = new AWS.DynamoDB.DocumentClient();

const params = {
  TableName : 'your-table-name',
  Item: {
     id: '12345',
  }
}

async function getItem(){
  try {
    await docClient.put(params).promise();
  } catch (err) {
    return err;
  }
}

exports.handler = async (event) => {
  try {
    await getItem()
    return { body: 'Successfully created item!' }
  } catch (err) {
    return { error: err }
  }
};
```

Push code.

```
$ amplify push
```

Test the function.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/n0sub8hjcf24h5xtz3sy.png)


## gets data from GraphQL


```
$ npm install axios, graphql-tag, graphql
```

Update the _index.js_

```
/* Amplify Params - DO NOT EDIT
	API_<Your API name>_GRAPHQLAPIENDPOINTOUTPUT
	API_<Your API name>_GRAPHQLAPIIDOUTPUT
	API_<Your API name>_GRAPHQLAPIKEYOUTPUT
	API_<Your API name>_PROPERTYTABLE_ARN
	API_<Your API name>_PROPERTYTABLE_NAME
	ENV
	REGION
Amplify Params - DO NOT EDIT */
const axios = require('axios');
const gql = require('graphql-tag');
const graphql = require('graphql');
const { print } = graphql;

const listPropertys = gql`
  query listPropertys {
    listPropertys {
      items {
        id
        name
      }
    }
  }
`

exports.handler = async (event) => {
  try {
    const graphqlData = await axios({
      url: process.env.API_<Your API name>_GRAPHQLAPIENDPOINTOUTPUT,
      method: 'post',
      headers: {
        'x-api-key': process.env.API_<Your API name>_GRAPHQLAPIKEYOUTPUT
      },
      data: {
        query: print(listPropertys),
      }
    });
    const body = {
        graphqlData: graphqlData.data.data.listPropertys
    }
    return {
        statusCode: 200,
        body: JSON.stringify(body),
        headers: {
            "Access-Control-Allow-Origin": "*",
        }
    }
  } catch (err) {
    console.log('error posting to appsync: ', err);
  } 
}
```

Push code.

```
$ amplify push
```

Test the function.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/1whwl2oc1h8rwi4rkmel.png)