State of REST
By: Curtis Maloney
FunkyBob on #django
Introduction
(aka: Who is this guy?)
- Started using Python 1.5
- Started using Django 0.91
-
django-nap
- django-rated
- Kogan (IE7 Tax)
The contenders
TastyPie (v0.9.16) [Since Mar 2010](2,111)
- Incumbent
- Has _everything_
- Monolithic "Resource" design
Django REST Framework (v2.3) [Since Dec 2010](1,297)
- v2.0 recently major redesign
- CBV + Serialiser
django-nap (v0.12.2) [Since Dec 2012](65)
- Small, simple, fast
- Publisher + Serialiser
Django API Frameworks: Features
- Authorisation/Authentication
- Data formats
- Serialiser
- Shapes
- Pagination
- Rate limiting
- Filtering
- API Versioning
- Generic Views
- Use in Views
Authentication
Who are you?
Authentication:
TastyPie
- HTTP Basic
- HTTP Digest
- API Key
- Session/Django
- OAuth 1.0a
- Multi / Custom
Authentication:
DRF
-
HTTP Basic
-
HTTP Digest *
-
API Key
-
Session/Django
-
OAuth 1.0a
-
OAuth 2
-
Custom
*requires 3rd party tool
Authentication:
Nap
None*
Authorisation:
May I?
Authorisation:
TastyPie
Per-Publisher "authorization" provider.
- read_list
- read_detail
- create_list
- create_detail
- update_list
- update_detail
- delete_list
- delete_detail
AuthoriSation:
DRF
- Global, shared, per-view.
has_permission(request, view)
has_object_permission(request, view, obj)
Authorisation:
Nap
@permit(test_func)
Data Formats
| Format | TastyPie | DRF | Nap |
|---|---|---|---|
| JSON |
|
|
|
| JSONP |
|
|
|
| XML |
|
|
|
| YAML |
|
|
|
| HTML (forms) |
|
|
|
| PLIST |
|
|
|
| MsgPack |
|
|
|
Serialiser
From object to data, and back again!
| Framework | Structure | Stateful? | Pattern |
|---|---|---|---|
| TastyPie | Monolitic | Stateless | Build + Set |
| DRF | Stand-alone | Stateful | restore_object |
| Nap | Stand-alone | Stateless | restore_object |
Shapes
TastyPie
Can define fields as list/detail only.
DRF
Per-view selection.
Nap
Per-view selection.
Pagination
TastyPie
Custom class.
Offset + Limit
DRF
Django native.
Page + Size
Nap
Django native.
Page + Size / Offset + Limit
*Page granular
Rate Limiting
TastyPie
Built-in
DRF
Built-in.
Global or Scoped
Anon or User
Nap
None.
(use django-rated)
Filtering
TastyPie
Django ORM
Whitelist
DRF
Pluggable
Whitelist
Nap
None*
Override Publisher
get_object_list
API Versioning
TastyPie
Resource wrapperDRF
Router + ViewSet*Nap
Publisher wrapper.Generic Views
TastyPie
None
Nap
Not Yet
Generic Views
DRF
- GenericAPIView
Mixins
- ListModelMixin
- CreateModelMixin
- RetrieveModelMixin
- UpdateModelMixin
- DestroyModelMixin
Concrete View Classes
- CreateAPIView
- ListAPIView
- RetrieveAPIView
- DestroyAPIView
- UpdateAPIView
- ListCreateAPIView
- RetrieveUpdateAPIView
- RetrieveDestroyAPIView
- RetrieveUpdateDestroyAPIView
Use in views
TastyPie: clumsy
Need to replicate a major internal function.
resource = ThingResource()
def thing_list(request, **kwargs):
base_bundle = self.build_bundle(request=request)
objects = resource.obj_get_list(bundle=base_bundle, **resource.remove_api_resource_names(kwargs))
sorted_objects = resource.apply_sorting(objects, options=request.GET)
paginator = resource._meta.paginator_class(request.GET,
sorted_objects,
resource_uri=resource.get_resource_uri(),
limit=resource._meta.limit,
max_limit=resource._meta.max_limit,
collection_name=resource._meta.collection_name
)
to_be_serialized = paginator.page()
bundles = [
resource.full_dehydrate(
resource.build_bundle(obj=obj, request=request),
for_list=True
)
for obj in to_be_serialized[resource._meta.collection_name]
]
to_be_serialized[resource._meta.collection_name] = bundles
to_be_serialized = resource.alter_list_data_to_serialize(request, to_be_serialized)
return render(request, 'thing/thing_list.html', {'resource': to_be_serialized})
Use in views
DRF
Core design!
Use in views
Nap: Simpler
def thing_list(request, **kwargs):
try:
publisher = ThingPublisher(request, **kwargs)
data = publisher.get_page(publisher.get_object_list())
serialiser = publisher.get_serialiser()
data['objects'] = serialiser.list_deflate(data['objects'])
except http.BaseHttpResponse as e:
return e
return render(request, 'thing/thing_list.html', {'resource': data})
Questions?
Thanks for listening!
HTH hAND!
github.com/funkybob/django-nap
State of REST
By Curtis Maloney
State of REST
- 1,496