Using Lambda with AWS Amplify with Go

I have a chance to use Amplify often, but I thought that I have hardly used Lambda via Amplify, so I decided to use it. And I can use Go with Lambda, but I feel like I haven't used it properly, so I'd like to use it.

Function seems to be usable

FUNCTIONS - Overview https://docs.amplify.aws/cli/function

environment

Try using

Preface

Set up amplify in the setting to use vue. For more information, start here. https://docs.amplify.aws/start/getting-started/installation/q/integration/vue

$ vue create myamplifyproject
$ cd myamplifyproject
$ npm install
$ amplify init
$ npm install aws-amplify @aws-amplify/ui-vue
$ vi src/main.js
$ npm run serve

amplify.png

add function

$ amplify add function
? Select which capability you want to add: Lambda function (serverless function)
? Provide a friendly name for your resource to be used as a label for this category in the project: myamplifyproject3e7c
0b2b
? Provide the AWS Lambda function name: myamplifyproject3e7c0b2b
? Choose the runtime that you want to use: Go
go executable was not found in PATH, make sure it's available. It can be installed from https://golang.org/doc/install
Only one template found - using Hello World by default.
? Do you want to access other resources in this project from your Lambda function? No
? Do you want to invoke this function on a recurring schedule? No
? Do you want to configure Lambda layers for this function? No
? Do you want to edit the local lambda function now? Yes
Please edit the file in your editor: /mnt/c/Users/user/myamplifyproject/amplify/backend/function/myamplifyproject3e7c0b2b/src/main.go
? Press enter to continue
Successfully added resource myamplifyproject3e7c0b2b locally.

Next steps:
Check out sample function code generated in <project-dir>/amplify/backend/function/myamplifyproject3e7c0b2b/src
"amplify function build" builds all of your functions currently in the project
"amplify mock function <functionName>" runs your function locally
"amplify push" builds all of your local backend resources and provisions them in the cloud
"amplify publish" builds all of your local backend and front-end resources (if you added hosting category) and provisions them in the cloud

Then a file called main.go was created.

main.go


package main

import (
  "fmt"
  "context"
  "github.com/aws/aws-lambda-go/lambda"
)

type MyEvent struct {
  Name string `json:"name"`
}

func HandleRequest(ctx context.Context, name MyEvent) (string, error) {
  return fmt.Sprintf("Hello %s!", name.Name ), nil
}

func main() {
  lambda.Start(HandleRequest)
}

Let's get github.com/aws/aws-lambda-go/lambda.

$ go get github.com/aws/aws-lambda-go/lambda

Try it out

$ amplify function build
? Are you sure you want to continue building the resources? Yes
✔ All resources are built.
$ amplify mock function myamplifyproject3e7c0b2b
? Provide the path to the event JSON object relative to /mnt/c/Users/masra/myamplifyproject/amplify/backend/function/mya
mplifyproject3e7c0b2b src/event.json
Starting execution...
Local invoker binary was not found, building it...
Launching Lambda process, port: 8000
Result:
Hello Amplify!
Finished execution.

After building with amplify function build, it seems that it can be executed locally withamplify mock function [functionname]. It seems that it uses a mechanism like sam.

deploy

You can deploy with the familiar amplify push & amplify publish. People using cli are via git Before that, I'll also do hosting add. Since it is a trial, I will deploy it directly to S3.

$ amplify hosting add
? Select the plugin module to execute Amazon CloudFront and S3
? Select the environment setup: DEV (S3 only with HTTP)
? hosting bucket name myamplifyproject-20210102225615-hostingbucket
? index doc for the website index.html
? error doc for the website index.html

You can now publish your app using the following command:
Command: amplify publish
$ amplify push
| Category | Resource name            | Operation | Provider plugin   |
| -------- | ------------------------ | --------- | ----------------- |
| Function | myamplifyproject3e7c0b2b | Create    | awscloudformation |
| Hosting  | S3AndCloudFront          | Create    | awscloudformation |
? Are you sure you want to continue? Yes
$ amplify publish
✔ Successfully pulled backend environment test from the cloud.

Current Environment: test

| Category | Resource name            | Operation | Provider plugin   |
| -------- | ------------------------ | --------- | ----------------- |
| Function | myamplifyproject3e7c0b2b | Create    | awscloudformation |
| Hosting  | S3AndCloudFront          | Create    | awscloudformation |
? Are you sure you want to continue? Yes
⠋ Updating resources in the cloud. This may take a few minutes...

...

✔ All resources are updated in the cloud

Hosting endpoint: http://myamplifyproject-20210102233234-hostingbucket-test.s3-website-ap-northeast-1.amazonaws.com


> [email protected] build /mnt/c/Users/masra/myamplifyproject
> vue-cli-service build


⠋  Building for production...

...

frontend build command exited with code 0
Publish started for S3AndCloudFront
✔ Uploaded files successfully.
Your app is published successfully.
http://myamplifyproject-20210102233234-hostingbucket-test.s3-website-ap-northeast-1.amazonaws.com

・ ・ Well, I was able to deploy. The default screen of vue can be displayed.

The function was created like this.

amplify3.png

Hate? There is no api gateway, but how do you do it? It only describes how to use it behind AppSync or start it from Schedule. Isn't it supposed to be used like a webapi?

try adding add api.

Can it be used as a REST API? I thought, so I will try it.

$ amplify add api
? Please select from one of the below mentioned services: REST
? Provide a friendly name for your resource to be used as a label for this category in the project: api090983e4
? Provide a path (e.g., /book/{isbn}): /items
? Choose a Lambda source Use a Lambda function already added in the current Amplify project
? Choose the Lambda function to invoke by this path myamplifyproject3e7c0b2b
? Restrict API access Yes
? Who should have access? Authenticated and Guest users
? What kind of access do you want for Authenticated users? create, read, update, delete
? What kind of access do you want for Guest users? create, read, update, delete
Successfully added auth resource locally.
? Do you want to add another path? No
Successfully added resource api090983e4 locally

Some next steps:
"amplify push" will build all your local backend resources and provision it in the cloud
"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud

Then amplify push.

$ amplify push
✔ Successfully pulled backend environment test from the cloud.

Current Environment: test

| Category | Resource name            | Operation | Provider plugin   |
| -------- | ------------------------ | --------- | ----------------- |
| Auth     | cognito557e6fef          | Create    | awscloudformation |
| Api      | api090983e4              | Create    | awscloudformation |
| Function | myamplifyproject3e7c0b2b | No Change | awscloudformation |
| Hosting  | S3AndCloudFront          | No Change | awscloudformation |
? Are you sure you want to continue? Yes
⠼ Updating resources in the cloud. This may take a few minutes...

...

REST API endpoint: https://uyyhhs6ca8.execute-api.ap-northeast-1.amazonaws.com/test

amplify4.png

O. It was big.

However, it says {"message ":" Missing Authentication Token "}. Somehow, Auth resources have been created without permission. It seems that it can not be executed unless it is certified by Cognito. If you use it from Amplify, that's fine.

However, this time I just want to skip that area and just do it for the time being. Do you want to access other resources in this project from your Lambda function? I think the reason is that I changed it to No, so I will try to set it to Yes this time.

Add funtion

$ amplify function add
? Select which capability you want to add: Lambda function (serverless function)
? Provide a friendly name for your resource to be used as a label for this category in the project: myamplifyproject2451
e9a2
? Provide the AWS Lambda function name: myamplifyproject2451e9a2
? Choose the runtime that you want to use: Go
Only one template found - using Hello World by default.
? Do you want to access other resources in this project from your Lambda function? Yes
? Select the category

You can access the following resource attributes as environment variables from your Lambda function

? Do you want to invoke this function on a recurring schedule? No
? Do you want to configure Lambda layers for this function? No
? Do you want to edit the local lambda function now? Yes
Please edit the file in your editor: /mnt/c/Users/user/myamplifyproject/amplify/backend/function/myamplifyproject2451e9a2/src/main.go
? Press enter to continue
Successfully added resource myamplifyproject2451e9a2 locally.

Next steps:
Check out sample function code generated in <project-dir>/amplify/backend/function/myamplifyproject2451e9a2/src
"amplify function build" builds all of your functions currently in the project
"amplify mock function <functionName>" runs your function locally
"amplify push" builds all of your local backend resources and provisions them in the cloud
"amplify publish" builds all of your local backend and front-end resources (if you added hosting category) and provisions them in the cloud
$ $ amplify add api
? Please select from one of the below mentioned services: REST
? Provide a friendly name for your resource to be used as a label for this category in the project: api62457bd3
? Provide a path (e.g., /book/{isbn}): /hage
? Choose a Lambda source Use a Lambda function already added in the current Amplify project
? Choose the Lambda function to invoke by this path myamplifyproject2451e9a2
? Restrict API access Yes
? Who should have access? Authenticated and Guest users
? What kind of access do you want for Authenticated users? create, read, update, delete
? What kind of access do you want for Guest users? create, read, update, delete
? Do you want to add another path? No
Successfully added resource api62457bd3 locally

Some next steps:
"amplify push" will build all your local backend resources and provision it in the cloud
"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud
$ amplify push
✔ Successfully pulled backend environment test from the cloud.

Current Environment: test

| Category | Resource name            | Operation | Provider plugin   |
| -------- | ------------------------ | --------- | ----------------- |
| Api      | api7dcd31c5              | Create    | awscloudformation |
| Auth     | cognito557e6fef          | Create    | awscloudformation |
| Api      | api090983e4              | Create    | awscloudformation |
| Function | myamplifyproject3e7c0b2b | No Change | awscloudformation |
| Function | myamplifyproject2451e9a2 | Create    | awscloudformation |
| Hosting  | S3AndCloudFront          | No Change | awscloudformation |
? Are you sure you want to continue? Yes
⠼ Updating resources in the cloud. This may take a few minutes...

...

REST API endpoint: https://xdewrmoiva.execute-api.ap-northeast-1.amazonaws.com/test

Hmm ... But it's no good. Is Token required because IAM authentication is attached?

amplify5.png

https://github.com/aws-amplify/amplify-cli/blob/fad6377bd384862ca4429cb1a83eee90efd62b58/packages/amplify-category-api/src/provider-utils/awscloudformation/service-walkthroughs/apigw-walkthrough.ts#L246 https://github.com/aws-amplify/amplify-cli/blob/master/packages/amplify-category-api/resources/awscloudformation/cloudformation-templates/apigw-cloudformation-template-default.json.ejs#L248

It seems that IAM certification is essential even if you look at this. Either auth or unauth. Well, it's okay because it's originally used via Amplify authentication.

There is no choice but to hit the API via Vue.

Why, I will try to hit the API properly. auth seems to have entered at the time of add api, so just rewrite vue a little. I'm reusing HelloWorld.vue. Amplify is not authenticated. Assuming that the guest user is hitting. Even so, if you use the Amplify library, a token will be added when you make an API request, so you should be able to hit it.

src/components/HelloWorld.vue


<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <button @click="getHelloWorld">API.post</button>
  </div>
</template>

<script>
import { API } from 'aws-amplify';

export default {
  name: 'HelloWorld',
  data: function() {
    return {
      msg: ""
    }
  },
  methods: {
    getHelloWorld() {
      API.post('api5afc9d6e', '/hage', {
         response: true,
         body: {
           text: "Amplify"
         },
         headers: {}
      }).then(result => {
        console.log(result.data)
        this.msg = result.data.text
      }).catch(err => {
        console.log(err)
      })
    }
  }
}
</script>

So, if I hit the API as it is, an error occurred in CORS, so I may have to do Access-Allow-Origin in the Response Header. Please refer to here for GO + Lambda. https://qiita.com/coil_msp123/items/b1751dbe74ada7fdd5a1

So, main.go looks like this. I'm sorry to beat you.

main.go


package main

import (
  "fmt"
  "log"
  "encoding/json"
  "github.com/aws/aws-lambda-go/lambda"
  "github.com/aws/aws-lambda-go/events"
)

func HandleRequest(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
  reqBody := request.Body
  req := make(map[string]string)
  json.Unmarshal([]byte(reqBody), &req)

  req["text"] = fmt.Sprintf("Hello, %s!", req["text"])
  bytes, _ := json.Marshal(req)
  log.Print(string(bytes))

  return events.APIGatewayProxyResponse{
    Body:  string(bytes),
    StatusCode: 200,
    Headers: map[string]string{
        "Content-Type": "application/json",
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Headers": "withcredentials,origin,Accept,Authorization,Content-Type",
    },
  }, nil
}

func main() {
  lambda.Start(HandleRequest)
}

Don't forget go get github.com/aws/aws-lambda-go/events. So, also run amplify function build and amplify function update. Also amplify push.

But when you're done, open locahost: 8080 while doing npm run serve,

amplify7.png

You're good.

Finally

$ amplify delete

I will not forget. I've exposed the endpoint name and erased it properly.

Recommended Posts

Using Lambda with AWS Amplify with Go
[AWS] Using ini files with Lambda [Python]
Serverless scraping using selenium with [AWS Lambda] -Part 1-
AWS Lambda with PyTorch [Lambda import]
Dynamically move Amplify with Lambda
Web scraping using AWS lambda
[AWS] Create API with API Gateway + Lambda
Tweet WakaTime Summary using AWS Lambda
Using cgo with the go command
Create API with Python, lambda, API Gateway quickly using AWS SAM
Notify HipChat with AWS Lambda (Python)
Using PhantomJS with AWS Lambda until displaying the html of the website
Try using Dropbox API v2 with Go
Regularly post to Twitter using AWS lambda!
[AWS] Link Lambda and S3 with boto3
Connect to s3 with AWS Lambda Python
[AWS] Do SSI-like things with S3 / Lambda
Python + Selenium + Headless Chromium with aws lambda
I just did FizzBuzz with AWS Lambda
Python with Go
[AWS SAM] Create API with DynamoDB + Lambda + API Gateway
Regular serverless scraping with AWS lambda + scrapy Part 1.8
Serverless application with AWS SAM! (APIGATEWAY + Lambda (Python))
[AWS] Try tracing API Gateway + Lambda with X-Ray
I tried connecting AWS Lambda with other services
Infrastructure construction automation with CloudFromation + troposphere + AWS Lambda
Try using S3 object upload and download with AWS SDK for Go v2
Make Lambda Layers with Lambda
Develop, run, and deploy AWS Lambda remotely using lambda-uploader
[AWS] Play with Step Functions (SAM + Lambda) Part.3 (Branch)
Check types_map when using mimetypes on AWS Lambda (Python)
How to set layer on Lambda using AWS SAM
Deploy Python3 function with Serverless Framework on AWS Lambda
Create a Layer for AWS Lambda Python with Docker
[AWS] Play with Step Functions (SAM + Lambda) Part.1 (Basic)
I want to AWS Lambda with Python on Mac!
Tweet from AWS Lambda
Manage your Amazon CloudWatch loggroup retention with AWS Lambda
AWS CDK with Python
Example of using lambda
Make ordinary tweets fleet-like with AWS Lambda and Python
Try AWS Lambda Destinations
[AWS] Play with Step Functions (SAM + Lambda) Part.2 (Parameter)
[AWS] What to do when you want to pip with Lambda
AWS Amplify + API Gateway + Lambda + Python returns a normal response
[AWS] Try adding Python library to Layer with SAM + Lambda (Python)
Output CloudWatch Logs to S3 with AWS Lambda (Pythyon ver)
Try automating Start / Stop for EC2 instances with AWS Lambda
I just built a virtual environment with AWS lambda layer
Challenge Problem 5 with Python: lambda ... Don't go deep into oneliner ... Don't
Site monitoring and alert notification with AWS Lambda + Python + Slack
Using X11 with ubuntu18.04 (C)
Draw Bezier curves with Go
When using optparse with iPython
Operate Db2 container with Go
Operate TwitterBot with Lambda, Python
Try using PythonTex with Texpad.
Using Graphviz with Jupyter Notebook
Getting Started with Go Assembly
[Python] Scraping in AWS Lambda
Messaging with AMQP using kombu