# 20230525 AWS API Gateway - API key and usage plan
###### tags: `AWS Learning Group`
## 前情提要
1. TODO list by Ian:
https://hackmd.io/2u6hJFMJTEmN_wEFxDZUFA
把這個先裝回來~
2. Sign up Postman: https://www.postman.com/
## What are usage plans and API keys?
A usage plan specifies who can access one or more deployed API stages and methods—and optionally sets the target request rate to start throttling requests. The plan uses API keys to identify API clients and who can access the associated API stages for each key.
## Set with AWS console
### Create API Key
API Gateway -> Your API -> API Keys
Actions -> Create API Key
### Create Usage Plans
Usage Plans -> Create -> Add API Stage
### Change Method to require API Key
Resources -> Method -> Method Request
**API Key Required** set to true
### Redeploy the API
Action -> Deploy API
Need to wait for about a minute.
## Set with serverless
In `serverless.yml`
```yaml=
provider:
name: aws
runtime: python3.8
region: us-east-1
environment:
DYNAMODB_TABLE: ${self:service}-${sls:stage}
iam:
role:
statements:
- Effect: Allow
Action:
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
Resource: "arn:aws:dynamodb:${aws:region}:*:table/${self:provider.environment.DYNAMODB_TABLE}"
# add this part
apiGateway:
apiKeys:
- MyFirstApiKey
usagePlan:
quota:
limit: 1000
period: MONTH
throttle:
burstLimit: 200
rateLimit: 100
```
Set private to true for each function:
```yaml=
functions:
create:
handler: todos/create.create
events:
- http:
path: todos
method: post
cors: true
# add this line
private: true
```
Run `sls deploy`
## Test with Postman
add a header of `x-api-key`

## Test with the frontend
```javascript=
const apiKey = 'YOUR_API_KEY'
```
```javascript=
export async function getServerSideProps() {
const res = await fetch(defaultEndpoint, {
// add this part
headers: {
"Content-Type": "application/json",
"x-api-key": apiKey,
},
});
const data = await res.json();
console.log(data)
return {
props: {
data
}
}
}
```
```javascript=
const handleDelete = async (id) => {
const response = await fetch(`${corsURL}${defaultEndpoint}/${id}`, {
method: "DELETE",
headers: {
"Content-Type": "application/json",
// add this header part
"x-api-key": apiKey,
},
})
.then(response => {
setUpdated(true);
})
.catch(error => {
console.error('Error:', error);
});
}
```
```javascript=
const handleSubmit = async (event) => {
event.preventDefault();
const response = await fetch(`${corsURL}${defaultEndpoint}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
// add this header part
"x-api-key": apiKey,
},
body: JSON.stringify(newTask),
})
.then(response => response.json())
.then(data => {
setUpdated(true);
setNewTask({text: ""});
console.log('Success:', data);
})
.catch(error => {
console.error('Error:', error);
});
}
```
## References
Creating and using usage plans with API keys (Official):
https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-api-usage-plans.html
Getting Started with serverless Framework |API Gateway and lambda | Lab 8| API Keys:
https://youtu.be/j_Gz-ACum80
Serverless:
https://www.serverless.com/plugins/serverless-add-api-key