Moving from Django Apps to Services
Upcoming SlideShare
Loading in...5
×
 

Moving from Django Apps to Services

on

  • 959 views

Slides from a talk on moving from Django applications to using services which enable better maintainability and scaling.

Slides from a talk on moving from Django applications to using services which enable better maintainability and scaling.

Statistics

Views

Total Views
959
Views on SlideShare
959
Embed Views
0

Actions

Likes
3
Downloads
11
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Moving from Django Apps to Services Moving from Django Apps to Services Presentation Transcript

  • Django Apps to Services
  • Craig Kerstiens @craigkerstiens work at @heroku
  • DjangoProject A collection of configuration and apps for a particular Website. (per Django Project)
  • DjangoProject A collection of configuration and apps for a particular Website.App A web application that does something. I.e. Weblog, Poll, Ticket system (per Django Project)
  • TableTable Table Table Table Table Table Table Table TableTable Table Table TableTable Table Table Table Table Table Table
  • TableTable Table Table Table Table Table Table Table TableTable Table Table TableTable Table Table Table Table Table Table
  • TableTable Table Table p Table Table Table p Table A Table TableTable Table Table TableTable Table Table Table Table Table Table
  • Monolithic Monster
  • Monolithic Monster$ ls mysitemodels.pyviews.pyforms.pyadmin.py
  • Monolithic Monster$ ls mysite $ wc -l models.pymodels.py 2557 models.pyviews.py $ wc -l view.spyforms.py 14241 views.pyadmin.py
  • Monolithic Monster $ ls mysite $ wc -l models.py models.py 2557 models.py views.py $ wc -l view.spy forms.py 14241 views.py admin.pyhttp://www.slideshare.net/jacobian/the-best-and-worst-of-django
  • Within Django
  • Within DjangoProject
  • Within DjangoProject App App App
  • Within DjangoProject Tickets App FAQ App FaqCreator App
  • Within Django cd myproject && find . manage.pyProject requirements.txt settings.py urls.py ./faq/admin.py ./faq/forms.py Tickets App ./faq/models.py ./faq/urls.py ./faq/views.py ./faqcreator/admin.py FAQ App ./faqcreator/forms.py ./faqcreator/models.py ./faqcreator/urls.py ./faqcreator/views.py ./tickets/admin.py FaqCreator App ./tickets/forms.py ./tickets/models.py ./tickets/urls.py ./tickets/views.py
  • Reusability
  • cd myproject && find . Reusability
  • cd myproject && find . Reusability manage.py requirements.txt settings.py urls.py ./faq/admin.py ./faq/forms.py ./faq/models.py ./faq/urls.py ./faq/views.py ./faqcreator/admin.py ./faqcreator/forms.py ./faqcreator/models.py ./faqcreator/urls.py ./faqcreator/views.py ./tickets/admin.py ./tickets/forms.py ./tickets/models.py ./tickets/urls.py ./tickets/views.py
  • cd myproject && find . Reusability cd myproject && find . manage.py requirements.txt manage.py settings.py requirements.txt urls.py settings.py ./faq/admin.py urls.py --> ./faq/forms.py ./faq/models.py cat myproject/requirements.txt ./faq/urls.py ./faq/views.py faq==0.1 ./faqcreator/admin.py faqcreator==0.1 ./faqcreator/forms.py tickets==0.1 ./faqcreator/models.py ./faqcreator/urls.py ./faqcreator/views.py ./tickets/admin.py ./tickets/forms.py ./tickets/models.py ./tickets/urls.py ./tickets/views.py
  • REUSABILITY means faster features due to DRY(Don’t Repeat Yourself )
  • REUSABILITY means faster features due to DRY(Don’t Repeat Yourself )REUSABILITY does not always mean SCALABILITYor MAINTAINABILITY
  • DjangoProject A collection of configuration and apps for a particular Website.App A web application that does something. I.e. Weblog, Poll, Ticket system (per Django Project)
  • DjangoProject A collection of configuration and apps for a particular Website.App A web application that does something. I.e. Weblog, Poll, Ticket systemService Method of communication over the web. Web APIs allow combination of multiple services
  • Tech imitate TeamsProject Company Tickets App Support FAQ App Knowledge Base FaqCreator App
  • Teams SupportKnowledge Base
  • Teams Grow App Support AppKnowledge Base
  • Teams Grow App Support AppKnowledge Base Billing
  • Teams Grow App Support Marketing AppKnowledge Base Billing
  • Teams Grow App Support Marketing API AppKnowledge Base Analytics Front End Billing Mobile Social
  • Apps Grow App Support Marketing API p s App A pKnowledge Base Analytics Front End3 App Billing Mobile Social
  • Apps Grow App Support p App s Marketing App API A p 9 AppKnowledge Base App Analytics App Front End App Billing App Mobile App Social
  • Apps Grow Support p s Marketing API Ap seKnowledge Base 9 deb a Analytics Front End Billing C o Mobile Social 1
  • SOA To the Rescue
  • SOA To the Rescue
  • SOA To the Rescue Photo by Paul Downey (psd on flickr)
  • ServiceDefined contract for communicating
  • ServiceDefined contract for communicating$ curl -O $FAQ_API/create/ -X “question=my question source=123”
  • In Python
  • In Pythondata = { ‘question’: “my question”, ‘source’: 123}requests.POST(os.environ[‘FAQ_API’] + ‘/create/’, data=data)
  • More than just API
  • More than just APIwww.google.com
  • More than just APIwww.google.commail.google.com
  • More than just APIwww.google.commail.google.comcalendar.google.com
  • More than just APIwww.google.commail.google.comcalendar.google.com..............google.com
  • Types of Services
  • Types of Servicessite
  • Types of Servicessitesubdomain
  • Types of ServicessitesubdomainAPI
  • Types of ServicessitesubdomainAPI - no auth required
  • Types of ServicessitesubdomainAPI - no auth required - API auth required
  • Types of ServicessitesubdomainAPI - no auth required - API auth required - user auth required
  • Where to Start App Support App Marketing App API AppKnowledge Base App Analytics App Front End App Billing App Mobile App Social
  • Where to Start App Support App Marketing API AppKnowledge Base Analytics Front End Billing Mobile App Social
  • 1 JavascriptMany pages
  • LA POSTA
  • Within Django cd myproject && find . manage.pyProject requirements.txt settings.py urls.py ./faq/admin.py ./faq/forms.py Tickets App ./faq/models.py ./faq/urls.py ./faq/views.py ./faqcreator/admin.py FAQ App ./faqcreator/forms.py ./faqcreator/models.py ./faqcreator/urls.py ./faqcreator/views.py ./tickets/admin.py FaqCreator App ./tickets/forms.py ./tickets/models.py ./tickets/urls.py ./tickets/views.py
  • Apps Depend on Other Apps
  • Apps Depend on Other Appsfaq creator
  • Apps Depend on Other Appsfaq creator faq app
  • Apps Depend on Other Appsfaq creator faq appticket
  • Apps Depend on Other Appsfaq creator faq appticket faq app
  • Apps Depend on Other Appsfaq creator faq app version == 0.1ticket faq app version == 0.2
  • Apps Depend on Other Appspip install faq==0.1pip install faq==0.2pip freezefaq==0.2
  • Apps Depend on Other Appsfaq creator faq app version == 0.1ticket faq app version == 0.2
  • Back to APIs
  • What’s a serviceProvider API_HOST= http://127.0.0.1
  • What’s a serviceProvider API_HOST= http://127.0.0.1Endpoint /v1/create/
  • What’s a serviceProvider API_HOST= http://127.0.0.1Endpoint /v1/create/Contract { ‘question’: ‘foo bar’, ‘source’: 123 }
  • App
  • AppURLs Views Models
  • AppURLs Views Models ServiceProvider Endpoint Contract
  • A SERVICE means REUSABILITYand enables SCALABILITY andMAINTAINABILITY
  • Where to start
  • Where to start1. If you’re monolithic, break up the apps first
  • Where to start1. If you’re monolithic, break up the apps first2. Port something that doesn’t require user
  • Where to start1. If you’re monolithic, break up the apps first2. Port something that doesn’t require user3. Port where you have many dependencies
  • Porting an App models.pyclass Faq(models.Model): title = models.CharField(max_length=100) source = models.IntegerField(blank=True, null=True) description = models.TextField() solution = models.TextField() def __unicode__(self): return self.title
  • Porting an App faqcreator/views.pyfrom faq.models import faqi = Faq(title=‘foo’, description=‘bar’, solution=’la posta’)i.save()
  • Turn it into an API
  • Turn it into an API1. pip install django-tastypie
  • Turn it into an API1. pip install django-tastypie2. add tastypie to INSTALLED_APPS
  • Turn it into an API1. pip install django-tastypie2. add tastypie to INSTALLED_APPS3. define your APIs
  • Create your APIfrom faq/api.py tastypie.resources import ModelResourcefrom faq.models import Faqfrom django.contrib.auth.models import Userfrom tastypie.authentication import BasicAuthentication, DjangoAuthorizationfrom tastypie.authorization import Authorizationclass FaqResource(ModelResource): class Meta: queryset = Faq.objects.all() resource_name = faq list_allowed_methods = [get, post] authentication = BasicAuthentication() authorization = Authorization() def obj_create(self, bundle, request=None, **kwargs): return super(FaqResource, self).obj_create(bundle, request, user=request.user) def apply_authorization_limits(self, request, object_list): return object_list.filter(user=request.user)
  • Create your API api.pyclass FaqResource(ModelResource): class Meta: queryset = Faq.objects.all() resource_name = faq list_allowed_methods = [get, post] authentication = BasicAuthentication() authorization = Authorization() def obj_create(self, bundle, request=None, **kwargs): return super(FaqResource, self).obj_create( bundle, request, user=request.user) def apply_authorization_limits(self, request, object_list): return object_list.filter(user=request.user)
  • Create your API api.pyclass FaqResource(ModelResource): class Meta: queryset = Faq.objects.all() resource_name = faq list_allowed_methods = [get, post] authentication = BasicAuthentication() authorization = Authorization() def obj_create(self, bundle, request=None, **kwargs): return super(FaqResource, self).obj_create( bundle, request, user=request.user) def apply_authorization_limits(self, request, object_list): return object_list.filter(user=request.user)
  • Create your API api.pyclass FaqResource(ModelResource): class Meta: queryset = Faq.objects.all() resource_name = faq list_allowed_methods = [get, post] authentication = BasicAuthentication() authorization = Authorization() def obj_create(self, bundle, request=None, **kwargs): return super(FaqResource, self).obj_create( bundle, request, user=request.user) def apply_authorization_limits(self, request, object_list): return object_list.filter(user=request.user)
  • Create your API api.pyclass FaqResource(ModelResource): class Meta: queryset = Faq.objects.all() resource_name = faq list_allowed_methods = [get, post] authentication = BasicAuthentication() authorization = Authorization() def obj_create(self, bundle, request=None, **kwargs): return super(FaqResource, self).obj_create( bundle, request, user=request.user) def apply_authorization_limits(self, request, object_list): return object_list.filter(user=request.user)
  • Create your API api.pyclass FaqResource(ModelResource): class Meta: queryset = Faq.objects.all() resource_name = faq list_allowed_methods = [get, post] authentication = BasicAuthentication() authorization = Authorization() def obj_create(self, bundle, request=None, **kwargs): return super(FaqResource, self).obj_create( bundle, request, user=request.user) def apply_authorization_limits(self, request, object_list): return object_list.filter(user=request.user)
  • Create your API api.pyclass FaqResource(ModelResource): class Meta: queryset = Faq.objects.all() resource_name = faq list_allowed_methods = [get, post] authentication = BasicAuthentication() authorization = Authorization() def obj_create(self, bundle, request=None, **kwargs): return super(FaqResource, self).obj_create( bundle, request, user=request.user) def apply_authorization_limits(self, request, object_list): return object_list.filter(user=request.user)
  • Create your API urls.pyfrom faq.api import FaqResourcefrom tastypie.api import Apiv1_api = Api(api_name=v1)v1_api.register(FaqResource())urlpatterns = patterns(, url(r^api/, include(v1_api.urls)),)
  • Use your APIcurl -H "Content-Type: application/json" --user admin:testing -X POST --data {"title": "New FAQ", "source": "1", "description": "foo", "solution": "bar"} http://127.0.0.1:8000/api/v1/faq/
  • Use it in Python
  • Use it in Pythondata = { title: New FAQ, source: 1, description: foo, solution: bar}r = requests.post(os.environ[‘FAQ_API’] + "api/v1/faq/", data=data, auth=(admin, testing))
  • Version Bump
  • Version Bumpdata = { title: New FAQ, source: 1, description: foo, solution: bar, related: [123, 456]}r = requests.post(os.environ[‘FAQ_API’] + "api/v2/faq/", data=data, auth=(admin, testing))
  • Version Bump
  • Version Bumpdata = { title: New FAQ, source: 1, description: foo, solution: bar, related: [123, 456]}r = requests.post(os.environ[‘FAQ_API’] + "api/v2/faq/", data=data, auth=(admin, testing))
  • In our Applicationfaq_creator/views.py ticket/views.py
  • In our Application faq_creator/views.pyr = requests.post(os.environ[‘FAQ_API’] + "api/v2/faq/", data=data, auth=(admin, testing)) ticket/views.pyr = requests.post(os.environ[‘FAQ_API’] + "api/v1/faq/", data=data, auth=(admin, testing))
  • cd myproject && find . Reusability cd myproject && find . manage.py requirements.txt manage.py settings.py requirements.txt urls.py settings.py ./faq/admin.py urls.py --> ./faq/forms.py ./faq/models.py cat myproject/requirements.txt ./faq/urls.py ./faq/views.py faq==0.1 ./faqcreator/admin.py faqcreator==0.1 ./faqcreator/forms.py tickets==0.1 ./faqcreator/models.py ./faqcreator/urls.py ./faqcreator/views.py ./tickets/admin.py ./tickets/forms.py ./tickets/models.py ./tickets/urls.py ./tickets/views.py
  • Maintainability/Scalability/Agilitycd myproject && find . ls projects manage.py faq-service requirements.txt myproject settings.py cd faq-service && find . urls.py manage.py requirements.txtcat myproject/requirements.txt faq==0.1 --> settings.py urls.py cd myproject && find . faqcreator==0.1 tickets==0.1 manage.py requirements.txt settings.py urls.py cat myproject/requirements.txt faqcreator==0.1 tickets==0.1
  • Maintainability/Scalability/Agility
  • Maintainability/Scalability/Agility Faq Project - Its own Django project - 1 Django app - Own database - Own deployment
  • Maintainability/Scalability/AgilityMy Project Faq Project - Contained Django Project - Its own Django project - 2 Django apps - 1 Django app - Own database - Own database - Own deployment - Own deployment
  • Take aways
  • Take aways1. Start non-critical (Cheat)2. Create services where theres app reuse3. Create services where theres pain4. Start small
  • Others
  • Others1. Expect APIs to fail2. Flask is great for APIs3. Make it easy to setup/test
  • Fin. Resourceshttp://www.craigkerstiens.comhttp://bit.ly/djangoappstoservices/http://www.12factor.nethttp://github.com/craigkerstiens/