This commit is contained in:
dzikafoczka 2024-12-22 21:11:54 +01:00
commit 71dd0a607a
2 changed files with 232 additions and 0 deletions

125
README.md Normal file
View File

@ -0,0 +1,125 @@
## AWS REST Web Service
Instrukcja uruchomienia web serwisu RESTowego na platformie AWS przy użyciu `AWS Lambda`, `API Gateway` oraz `DynamoDB`:
1. Utwórz tabelę w `DynamoDB`:
- Przejdź do konsoli AWS i wybierz usługę `DynamoDB`.
- Kliknij przycisk `Create table`.
- Wprowadź nazwę tabeli: `Posts`.
- Wprowadź klucz główny: `id` typu `String`.
- Kliknij przycisk `Create`.
2. Utwórz funkcję w `AWS Lambda` do obsługi żądań `CRUD`:
- Przejdź do konsoli AWS i wybierz usługę `Lambda`.
- Kliknij przycisk `Create function`.
- Wybierz opcję `Author from scratch`.
- Wprowadź nazwę funkcji, np. `postsCRUD`.
- Wybierz runtime, np. `Python 3.13`.
- W sekcji `Change default execution role` wybierz opcję `Use an existing role` i wybierz rolę `LabRole`.
- Kliknij przycisk `Create function`.
- Wklej poniższy kod do edytora funkcji:
```python
import json
import boto3
from decimal import Decimal
dynamodb = boto3.resource("dynamodb")
table = dynamodb.Table('Posts')
def lambda_handler(event, context):
print(event)
body = {}
statusCode = 200
try:
# Endpoint: DELETE /posts/{id}
if event['routeKey'] == "DELETE /posts/{id}":
table.delete_item(
Key={'id': event['pathParameters']['id']}
)
body = {"message": f"Deleted item with id {event['pathParameters']['id']}"}
# Endpoint: GET /posts/{id}
elif event['routeKey'] == "GET /posts/{id}":
response = table.get_item(
Key={'id': event['pathParameters']['id']}
)
if 'Item' in response:
body = response['Item']
else:
statusCode = 404
body = {"error": "Item not found"}
# Endpoint: GET /posts
elif event['routeKey'] == "GET /posts":
response = table.scan()
items = response.get('Items', [])
body = items
# Endpoint: POST /posts
elif event['routeKey'] == "POST /posts":
requestJSON = json.loads(event['body'])
table.put_item(
Item={
'id': str(requestJSON['id']), # DynamoDB keys must be strings
'userId': str(requestJSON['userId']),
'title': requestJSON['title'],
'body': requestJSON['body']
}
)
body = {"message": f"Created item with id {requestJSON['id']}"}
# Endpoint: PUT /posts/{id}
elif event['routeKey'] == "PUT /posts/{id}":
requestJSON = json.loads(event['body'])
table.update_item(
Key={'id': event['pathParameters']['id']},
UpdateExpression="SET userId = :userId, title = :title, body = :body",
ExpressionAttributeValues={
':userId': str(requestJSON['userId']),
':title': requestJSON['title'],
':body': requestJSON['body']
}
)
body = {"message": f"Updated item with id {event['pathParameters']['id']}"}
# Unsupported route
else:
statusCode = 400
body = {"error": f"Unsupported route: {event['routeKey']}"}
except Exception as e:
statusCode = 500
body = {"error": str(e)}
# Return the response
return {
"statusCode": statusCode,
"headers": {
"Content-Type": "application/json"
},
"body": json.dumps(body)
}
```
3. Utwórz HTTP API w `API Gateway` do przekierowywania żądań do funkcji `AWS Lambda`:
- Przejdź do konsoli AWS i wybierz usługę `API Gateway`.
- Kliknij przycisk `Create API`.
- Wybierz opcję `HTTP API`.
- Wprowadź nazwę API, np. `PostsAPI`.
- Przejdź przez formularz i utwórz API.
- Utwórz endpointy dla żądań `GET`, `POST`, `PUT` i `DELETE`, np.:
```
GET /posts
GET /posts/{id}
POST /posts
PUT /posts/{id}
DELETE /posts/{id}
```
- Utwórz i przypisz integrację z funkcją `AWS Lambda` dla każdego endpointu.
4. I gotowe. Możesz teraz uruchomić skrypt testowy `test.ipynb` do testowania web serwisu RESTowego. Pamiętaj, by zmienić adres URL API w skrypcie na Twój adres URL.
### Materiały
* https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-dynamo-db.html#http-api-dynamo-db-create-table

107
test.ipynb Normal file
View File

@ -0,0 +1,107 @@
{
"cells": [
{
"cell_type": "code",
"id": "initial_id",
"metadata": {
"collapsed": true,
"ExecuteTime": {
"end_time": "2024-12-22T20:11:38.991267Z",
"start_time": "2024-12-22T20:11:31.288506Z"
}
},
"source": [
"WEBSERVICE_URL = \"https://z309w7i8t3.execute-api.us-east-1.amazonaws.com/posts\"\n",
"\n",
"import requests\n",
"from faker import Faker\n",
"fake = Faker()\n",
"\n",
"n = 3\n",
"\n",
"outs = []\n",
"outs2 = []\n",
"\n",
"OK = True\n",
"\n",
"for i in range(n):\n",
" try:\n",
" outs.append(requests.post(WEBSERVICE_URL, json={'userId': 1, 'title': fake.catch_phrase(), 'body': fake.text()}).json())\n",
" except:\n",
" print(\"Nie udało się dodać nowego zasobu\")\n",
" OK = False\n",
"\n",
"for i in range(n):\n",
" try:\n",
" tmp = requests.get(WEBSERVICE_URL+'/'+str(outs[i]['id'])).json()\n",
" if tmp != outs[i]:\n",
" print(\"Pobrany zasób nie jest zgodny ze wzrocem\")\n",
" OK = False\n",
" except:\n",
" print(\"Nie udało się pobrać zasobu: \"+WEBSERVICE_URL+'/'+str(outs[i]['id']))\n",
" OK = False\n",
"\n",
"for i in range(n):\n",
" try:\n",
" outs2.append(requests.put(WEBSERVICE_URL+'/'+str(outs[i]['id']), json={'userId': 1, 'title': fake.catch_phrase(), 'body': fake.text()}).json())\n",
" except:\n",
" OK = False\n",
" print(\"Nie udało się zmodyfikować zasobu: \"+WEBSERVICE_URL+'/'+str(outs[i]['id']))\n",
"\n",
"for i in range(n):\n",
" try:\n",
" tmp = requests.get(WEBSERVICE_URL+'/'+str(outs[i]['id'])).json()\n",
" if tmp != outs2[i]:\n",
" print(\"Pobrany zasób nie jest zgodny ze zaktualizowanym wzrocem\")\n",
" OK = False\n",
" except:\n",
" print(\"Nie udało się pobrać zasobu: \"+WEBSERVICE_URL+'/'+str(outs[i]['id']))\n",
" OK = False\n",
"\n",
"for i in range(n):\n",
" try:\n",
" requests.delete(WEBSERVICE_URL+'/'+str(outs[i]['id']), data={'userId': 1, 'title': fake.catch_phrase(), 'body': fake.text()}).json()\n",
" except:\n",
" print(\"Nie udało się usunąć zasobu: \"+WEBSERVICE_URL+'/'+str(outs[i]['id']))\n",
" OK = False\n",
"\n",
"if OK:\n",
" print(\"==================\\nOK zaliczone\")\n",
"else:\n",
" print(\"==================\\nNie zaliczone\")"
],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"==================\n",
"OK zaliczone\n"
]
}
],
"execution_count": 15
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.6"
}
},
"nbformat": 4,
"nbformat_minor": 5
}