Django Declarative APIs v0.31¶
Overview¶
django-declarative-apis is a framework built on top of Django aimed at teams implementing RESTful APIs. It provides a simple interface to define endpoints declaratively. Some benefits to using django-declarative-apis:
Define endpoints declaratively
Define model-bound and unbound resource endpoints with a consistent interface
OAuth 1.0a authentication out of the box
Define resource and endpoint-bound tasks, promoting modularity
Define synchronous and asynchronous tasks (asynchronous tasks implemented with Celery)
Separation of concerns between request body processing and business logic
Quick Start¶
We are going to create a simple todo app that can only add tasks to a todo list.
Project Setup¶
Create a new project named dda_project and a new app called todo.
# create a new project directory
mkdir dda_todo_app
cd dda_todo_app
# create a virutal environment
python -m venv env
source env/bin/activate
# install django
pip install django
# create a new project
django-admin startproject dda_project
cd dda_project
# create a new app
python manage.py startapp todo
cd ..
Install django-declarative-apis¶
Clone django-declarative-apis repository.
git clone https://github.com/salesforce/django-declarative-apis.git
Django Config Settings Setup¶
Add the todo app and django-declarative-apis to the list of installed apps in settings.py
.
INSTALLED_APPS = ['django_declarative_apis','todo',]
Add the DDA required configuration to settings.py
.
# This will be used later in the process to find the correct EndpointResource.
# The EndpointResource is responsible for authentication and routing of the requests.
DECLARATIVE_ENDPOINT_RESOURCE_ADAPTER = (
"django_declarative_apis.adapters.EndpointResource"
)
# The authentication handler is used by endpoint resource to authenticate the requester.
DECLARATIVE_ENDPOINT_AUTHENTICATION_HANDLERS = [
(
(None, 'django_declarative_apis.authentication.oauthlib.oauth1.TwoLeggedOauth1Hint'),
'django_declarative_apis.authentication.oauthlib.oauth1.TwoLeggedOauth'
),
]
# This will be the default filters that will applied to all the endpoint definitions' responses
DECLARATIVE_ENDPOINT_DEFAULT_FILTERS = "todo.filters.TodoResponseFilter"
Models Setup¶
Let’s set up a Todo model in todo/models.py
.
from django.db import models
class Todo(models.Model):
task = models.CharField(max_length=255, null=False)
priority = models.CharField(max_length=255)
created_date = models.DateTimeField(auto_now_add=True)
completion_status = models.BooleanField(default=False)
def __str__(self):
return f"{self.task}"
Filters Setup¶
Let’s set up filters in todo/filters.py
that will decide the format of the API response.
from django_declarative_apis.machinery import filtering
from .models import Todo
TodoResponseFilter = {
Todo: {
'task': filtering.ALWAYS,
'priority': filtering.ALWAYS,
'created_date': filtering.ALWAYS,
'completion_status': filtering.ALWAYS
},
}
URLs¶
Let’s set up the URLs in todo/urls.py
.
from django.conf.urls import url
urlpatterns = [
url(
r"^tasks/$",
post=resource_adapter(post=resources.TodoUpdateDefinition,)
),
]
The important points to note here:
resource_adapter
is a helper function that will look into Django’s config settings and find the endpoint resource adapter to call. In our case,DECLARATIVE_ENDPOINT_RESOURCE_ADAPTER
is set toEndpointResource
, which is the endpoint resource that will be called.EndpointResource
will perform:Authentication configuration check.
Endpoint binding, which means routing the request to an endpoint definition based on the HTTP verb used and the required parameters accepted by the endpoint definition.
The endpoint binder then executes the authentication checks defined in the endpoint definition, which are
is_authorized
,is_permitted
, andis_valid
.
Once the endpoint binding is successful, the request will be routed to the endpoint definition that can handle it. In our case it will be routed to
resources.TodoUpdateDefinition
.
Note
All of the above-mentioned operations will be handled by the framework and will run in the background.
Resources Setup¶
Let’s set up our endpoint definition in a new file named todo/resources.py
. The endpoint definition is TodoUpdateDefinition
that will be used to create a new a task in the todo list.
from django_declarative_apis import machinery
from django_declarative_apis.machinery import field, endpoint_resource
from .models import Todo
class TodoResourceMixin:
consumer = None
_consumer_type = None
def is_authorized(self):
return True
class TodoUpdateDefinition(TodoResourceMixin, machinery.ResourceUpdateEndpointDefinition):
task = field(required=True, type=str)
priority = field(required=True, type=str)
completion_status = field(type=bool, default=False)
@endpoint_resource(type=Todo)
def resource(self):
task, created = Todo.objects.get_or_create(
task=self.task,
priority=self.priority,
completion_status=self.completion_status,
)
return task
The important points to note here:
Once the authentication and binding are successfully completed, the framework will run
TodoUpdateDefinition.resource()
, which will refer to the fields.fields will process the request data.
Note
If
aggregates
andtasks
are present, the framework will also be process those in this stage.By default DDA calls
TodoUpdateDefinition.response
, which returnsTodoUpdateDefinition.resource
as the response of the endpoint.Note
The default response can be overridden.
The format of the response will be determined by filters.
Note
All of the above-mentioned operations will be handled by the framework and will run in the background.
Contents: