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.
FUNCTIONS - Overview https://docs.amplify.aws/cli/function
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
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
$ 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.
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?
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
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?
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.
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
,
You're good.
$ amplify delete
I will not forget. I've exposed the endpoint name and erased it properly.
Recommended Posts