django meetup - 20100217 - django-piston€¦ · representational state transfer...

26
crea%ng res*ul/resource oriented webservices using Django

Upload: others

Post on 28-Jun-2020

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: django meetup - 20100217 - django-piston€¦ · Representational state transfer Setof(designcriteria forbuildingdistributedhypermediasystems inspired by(the(principles thatmade(the((World’Wide’Web

crea%ng  res*ul/resource  oriented  webservices  using  Django  

Page 2: django meetup - 20100217 - django-piston€¦ · Representational state transfer Setof(designcriteria forbuildingdistributedhypermediasystems inspired by(the(principles thatmade(the((World’Wide’Web

Representational state transfer

Set  of  design  criteria  for  building  distributed  hypermedia  systems  inspired  

by  the  principles  that  made  the    World  Wide  Web  succesful  

Page 3: django meetup - 20100217 - django-piston€¦ · Representational state transfer Setof(designcriteria forbuildingdistributedhypermediasystems inspired by(the(principles thatmade(the((World’Wide’Web

Principles

•  Client-­‐server  •  Stateless  •  Cacheable  •  Layered  system  •  Uniform  interface  –  Iden%fica%on  of  resources  – Manipula%on  of  resources  through  these  representa%ons  

–  Self-­‐descrip%ve  messages  – Hypermedia  as  the  engine  of  applica%on  state  

Page 4: django meetup - 20100217 - django-piston€¦ · Representational state transfer Setof(designcriteria forbuildingdistributedhypermediasystems inspired by(the(principles thatmade(the((World’Wide’Web

Resource Oriented Architecture

A  RESTful  architecture  for  designing  web  services  

Page 5: django meetup - 20100217 - django-piston€¦ · Representational state transfer Setof(designcriteria forbuildingdistributedhypermediasystems inspired by(the(principles thatmade(the((World’Wide’Web

Architecture

•  Tied  to  HTTP  •  Uniform  interface  •  Addressability  –  clean,  meaningful,  well  structured  

•  Safety  •  Idempotence  •  Connectedness  •  Statelesness  – No  state  means  scalable  and  reliable  

Page 6: django meetup - 20100217 - django-piston€¦ · Representational state transfer Setof(designcriteria forbuildingdistributedhypermediasystems inspired by(the(principles thatmade(the((World’Wide’Web

A resource

“A  resource  is  anything  important  enough  to  be  referenced  as  a  thing  in  itself”  

 -­‐-­‐  RESTful  Web  Services,  O’Reilly  

Page 7: django meetup - 20100217 - django-piston€¦ · Representational state transfer Setof(designcriteria forbuildingdistributedhypermediasystems inspired by(the(principles thatmade(the((World’Wide’Web

Has a representation

Data  format  documen%ng  current/intended  state  of  the  resource  

Page 8: django meetup - 20100217 - django-piston€¦ · Representational state transfer Setof(designcriteria forbuildingdistributedhypermediasystems inspired by(the(principles thatmade(the((World’Wide’Web

Used to transfer state

Client  is  able  to  change  server  state  by  sending  a  representa>on  of  the  new  state  of  a  resource.  

Page 9: django meetup - 20100217 - django-piston€¦ · Representational state transfer Setof(designcriteria forbuildingdistributedhypermediasystems inspired by(the(principles thatmade(the((World’Wide’Web

Django-piston

“A  mini-­‐framework  for  Django  for  crea%ng  RESTful  APIs.”  

Page 10: django meetup - 20100217 - django-piston€¦ · Representational state transfer Setof(designcriteria forbuildingdistributedhypermediasystems inspired by(the(principles thatmade(the((World’Wide’Web

Features

•  Ties  into  Django's  internal  mechanisms.  •  Supports  OAuth  out  of  the  box  (as  well  as  Basic/Digest  or  custom  auth.)  

•  Doesn't  require  tying  to  models,  allowing  arbitrary  resources.  

•  Speaks  JSON,  YAML,  Python  Pickle  &  XML  

Page 11: django meetup - 20100217 - django-piston€¦ · Representational state transfer Setof(designcriteria forbuildingdistributedhypermediasystems inspired by(the(principles thatmade(the((World’Wide’Web

Features

•  Ships  with  a  convenient  reusable  library  in  Python  

•  Respects  and  encourages  proper  use  of  HTTP  (status  codes,  ...)  

•  Has  built  in  (op%onal)  form  valida%on  (via  Django),  thro]ling,  etc.  

•  Supports  streaming,  with  a  small  memory  footprint.  

•  Stays  out  of  your  way.  

Page 12: django meetup - 20100217 - django-piston€¦ · Representational state transfer Setof(designcriteria forbuildingdistributedhypermediasystems inspired by(the(principles thatmade(the((World’Wide’Web

Build an API in 5 minutes! ;)

API  that  exposes  informa%on  about  countries  

Page 13: django meetup - 20100217 - django-piston€¦ · Representational state transfer Setof(designcriteria forbuildingdistributedhypermediasystems inspired by(the(principles thatmade(the((World’Wide’Web

The model

# models.pyfrom django.db import models

class Country(models.Model): name = models.CharField(blank=False,

max_length=100, db_index=True) slug = AutoSlugField(populate_from='name’)

Page 14: django meetup - 20100217 - django-piston€¦ · Representational state transfer Setof(designcriteria forbuildingdistributedhypermediasystems inspired by(the(principles thatmade(the((World’Wide’Web

Country overview

•  Request  to  /country/  will  result  in  a  JSON  representa%on  of  all  countries  (the  queryset)  

•  Request  to  /country/1/  will  result  in  returning  only  the  country  object  with  pk  1  

Page 15: django meetup - 20100217 - django-piston€¦ · Representational state transfer Setof(designcriteria forbuildingdistributedhypermediasystems inspired by(the(principles thatmade(the((World’Wide’Web

Implementation

# handlers.pyfrom piston.handler import BaseHandlerfrom models import Country

class CountryHandler(BaseHandler): model = Country allowed_methods = ('GET',)

# urls.pyfrom django.conf.urls.defaults import patterns, urlfrom piston.resource import Resourcefrom handlers import CountryHandler

urlpatterns = patterns('', url(r’^country/(?P<pk>[^/]+)/$',

Resource(CountryHandler) ),)  

Page 16: django meetup - 20100217 - django-piston€¦ · Representational state transfer Setof(designcriteria forbuildingdistributedhypermediasystems inspired by(the(principles thatmade(the((World’Wide’Web

Using slugs

•  Request  to  /country/  will  result  in  a  JSON  representa%on  of  all  countries  (the  queryset)  

•  Request  to  /country/netherlands/  will  result  in  returning  only  the  country  object  with  the  slug  field  set  to  netherlands  

Page 17: django meetup - 20100217 - django-piston€¦ · Representational state transfer Setof(designcriteria forbuildingdistributedhypermediasystems inspired by(the(principles thatmade(the((World’Wide’Web

Implementation # handlers.pyclass CountryHandler(BaseHandler): ... # Update pk to country_slug in urls.py def read(self, request, country_slug=None): if country_slug is not None: return get_object_or_404(Country,

slug=country_slug) else: return Country.objects.all()

Page 18: django meetup - 20100217 - django-piston€¦ · Representational state transfer Setof(designcriteria forbuildingdistributedhypermediasystems inspired by(the(principles thatmade(the((World’Wide’Web

Updating countries

•  PUT  Request  to  /country/1/  with  all  of  the  models  variables  will  result  in  a  change  of  the  resource  state  (to  the  new  desired  state)  

Page 19: django meetup - 20100217 - django-piston€¦ · Representational state transfer Setof(designcriteria forbuildingdistributedhypermediasystems inspired by(the(principles thatmade(the((World’Wide’Web

Implementation

# handlers.pyclass CountryHandler(BaseHandler): model = Country allowed_methods = ('GET', 'PUT')

...  

Page 20: django meetup - 20100217 - django-piston€¦ · Representational state transfer Setof(designcriteria forbuildingdistributedhypermediasystems inspired by(the(principles thatmade(the((World’Wide’Web

Validation of PUT

•  PUT  Request  to  /country/1/  should  be  validated  (and  if  incorrect,  PUT  should  not  change  the  state  of  the  system)  

Page 21: django meetup - 20100217 - django-piston€¦ · Representational state transfer Setof(designcriteria forbuildingdistributedhypermediasystems inspired by(the(principles thatmade(the((World’Wide’Web

Implementation

# handlers.pyfrom django import forms

class CountryForm(forms.ModelForm): class Meta: model = Country

class CountryHandler(BaseHandler): ..

@validate(CountryForm, 'PUT') def update(self, request, pk): super(CountryHandler, self).update(request, pk)  

Page 22: django meetup - 20100217 - django-piston€¦ · Representational state transfer Setof(designcriteria forbuildingdistributedhypermediasystems inspired by(the(principles thatmade(the((World’Wide’Web

Authentication

•  PUT  Request  to  /country/1/  should  be  validated  with  exis%ng  Django  users    

•  If  incorrect,  PUT  should  not  change  the  state  of  the  system  

Page 23: django meetup - 20100217 - django-piston€¦ · Representational state transfer Setof(designcriteria forbuildingdistributedhypermediasystems inspired by(the(principles thatmade(the((World’Wide’Web

Implementation

# urls.pyfrom piston.authentication import HttpBasicAuthentication

basic_auth = \HttpBasicAuthentication(realm='CountryService')

urlpatterns = patterns('', url(r'^(?P<country>[^/]+)/$’,

Resource(CountryHandler, authentication=basic_auth)),

)  

Page 24: django meetup - 20100217 - django-piston€¦ · Representational state transfer Setof(designcriteria forbuildingdistributedhypermediasystems inspired by(the(principles thatmade(the((World’Wide’Web

And more

•  Thro]ling  •  Custom  emi]ers  

•  Streaming  

Page 25: django meetup - 20100217 - django-piston€¦ · Representational state transfer Setof(designcriteria forbuildingdistributedhypermediasystems inspired by(the(principles thatmade(the((World’Wide’Web

Danki!

Ques%ons?  

Page 26: django meetup - 20100217 - django-piston€¦ · Representational state transfer Setof(designcriteria forbuildingdistributedhypermediasystems inspired by(the(principles thatmade(the((World’Wide’Web

Best practices

•  versioning  in  your  api  •  using  headers  -­‐>  localiza%on/content  nego%a%on  

•  make  a  separate  api  namespace  

•  have  each  func%onal  part  of  the  api  be  it's  own  app  (just  like  you  would  normally  do  with  django)