Create an api that operates on AWS DynamoDB with django REST Framework and boto3. Enable GET, POST, PUT, and DELETE operations.
Prepare the following table in advance and put some data in it. Table name: Fruits hash key: Name
Create django project (dynamo_operation) and app (api)
$ django-admin startproject dynamo_operation
$ cd dynamo_operation/
$ django-admin startapp api
Add rest_framework
and ʻapp config created earlier to
setting.py`.
dynamo_operation/setting.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework', #add to
'api.apps.ApiConfig', #add to
]
In django, prepare model
for DB creation and operation.
Since the request to DynamoDB uses boto3, model
is not necessary, but this time we preparedmodel (dynamo_model.py)
.
api/dynamo_model.py
class Fruit():
def __init__(self, name):
self.name = name
api/views.py
from rest_framework import status
from rest_framework.views import APIView
from rest_framework.response import Response
from api.dynamo_models import Fruit
from boto3 import client
dynamodb_client = client('dynamodb')
class DynamoRequest(APIView):
#Whole GET
def get(self, request):
response = []
items = dynamodb_client.scan(TableName='Fruits')['Items']
for item in items:
fruit = Fruit(item['Name']['S'])
fruit.price = item.get('Price',{}).get('N', '')
response.append(fruit.__dict__)
return Response(response)
def post(self, request):
request_data = request.data
item = {'Name': {'S': request_data['Name']}}
if 'Price' in request_data:
item['Price'] = {'N': request_data['Price']}
dynamodb_client.put_item(
TableName = 'Fruits',
Item = item
)
return Response(status=status.HTTP_201_CREATED)
class DynamoDetailRequest(APIView):
#Single GET
def get(self, request, pk):
item = dynamodb_client.get_item(
TableName = 'Fruits',
Key = {
'Name': {'S': pk},
}
)['Item']
fruit = Fruit(item['Name']['S'])
fruit.price = item.get('Price',{}).get('N', '')
return Response(fruit.__dict__)
def put(self, request, pk):
request_data = request.data
item = dynamodb_client.get_item(
TableName = 'Fruits',
Key = {
'Name': {'S': pk},
}
)['Item']
price = item.get('Price',{}).get('N', '0')
if 'Price' in request_data:
price = request_data['Price']
dynamodb_client.put_item(
TableName = 'Fruits',
Item = {
'Name': {'S': item['Name']['S']},
'Price': {'N': price}
}
)
return Response(status=status.HTTP_200_OK)
def delete(self, request, pk):
dynamodb_client.delete_item(
TableName = 'Fruits',
Key = {
'Name': {'S': pk},
}
)
return Response(status=status.HTTP_204_NO_CONTENT)
Process the request with class
which inherits ʻAPIView of
rest_framework.
DynamoRequest handles the request without the path parameter, and
DynamoDetailRequest handles the request with the path parameter (pk). By inheriting ʻAPIView
, it is possible to add the process corresponding to each method by preparing a function for each HTTP method.
api/urls.py
from django.urls import path
from api import views
urlpatterns = [
path('api/', views.DynamoRequest.as_view()),
path('api/<pk>/', views.DynamoDetailRequest.as_view())
]
Also edit ʻurls.py in the
dynamo_opration` folder
dynamo_opration/urls.py
from django.urls import path, include
urlpatterns = [
path('', include('api.urls')),
]
$ python manage.py runserver
$ curl http://127.0.0.1:8000/api/
#response
[{"name":"orange","price":"200"},{"name":"banana","price":"100"},{"name":"apple","price":"100"}]
POST
$ curl -X POST \
-H 'Content-Type:application/json' \
-d '{"Name": "peach", "Price": "400"}' \
http://127.0.0.1:8000/api/
Table after POST request
The peach item has been added.
Get apple item
$ curl http://127.0.0.1:8000/api/apple/
#response
{"name":"apple","price":"100"}
PUT Change apple price from 100-> 200
$ curl -X PUT \
-H 'Content-Type:application/json' \
-d '{"Price": "200"}' \
http://127.0.0.1:8000/api/apple/
Table after PUT request
DELETE Delete the peach item.
$ curl -X DELETE http://127.0.0.1:8000/api/peach/
Table after DELETE request
I created a REST API to operate DynamoDB with django REST Framework + boto3. This time, I prepared dynamodb_model.py to manage the model, but it may not have been necessary (I would like to improve the design around here in the future).
Recommended Posts