Moving from Django Apps to Services

118
Django Apps to Services

description

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

Transcript of Moving from Django Apps to Services

Page 1: Moving from Django Apps to Services

Django Apps to Services

Page 2: Moving from Django Apps to Services

Craig Kerstiens@craigkerstiens work at @heroku

Page 3: Moving from Django Apps to Services

Project A collection of configuration and apps for a particular Website.

(per Django Project)

Django

Page 4: Moving from Django Apps to Services

ProjectApp

A collection of configuration and apps for a particular Website.

A web application that does something. I.e. Weblog, Poll, Ticket system

(per Django Project)

Django

Page 8: Moving from Django Apps to Services

Monolithic Monster

Page 9: Moving from Django Apps to Services

Monolithic Monster$ ls mysitemodels.pyviews.pyforms.pyadmin.py

Page 10: Moving from Django Apps to Services

Monolithic Monster$ ls mysitemodels.pyviews.pyforms.pyadmin.py

$ wc -l models.py 2557 models.py$ wc -l view.spy 14241 views.py

Page 11: Moving from Django Apps to Services

Monolithic Monster$ ls mysitemodels.pyviews.pyforms.pyadmin.py

$ wc -l models.py 2557 models.py$ wc -l view.spy 14241 views.py

http://www.slideshare.net/jacobian/the-best-and-worst-of-django

Page 12: Moving from Django Apps to Services

Within Django

Page 13: Moving from Django Apps to Services

Project

Within Django

Page 14: Moving from Django Apps to Services

Project

App

App

App

Within Django

Page 15: Moving from Django Apps to Services

Project

App

App

App

Tickets

FAQ

FaqCreator

Within Django

Page 16: Moving from Django Apps to Services

Project

App

App

App

Tickets

FAQ

FaqCreator

Within Djangocd myproject && find .manage.pyrequirements.txtsettings.pyurls.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

Page 17: Moving from Django Apps to Services

Reusability

Page 18: Moving from Django Apps to Services

cd myproject && find .Reusability

Page 19: Moving from Django Apps to Services

cd myproject && find .manage.pyrequirements.txtsettings.pyurls.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

Reusability

Page 20: Moving from Django Apps to Services

cd myproject && find .manage.pyrequirements.txtsettings.pyurls.py

cat myproject/requirements.txtfaq==0.1faqcreator==0.1 tickets==0.1

cd myproject && find .manage.pyrequirements.txtsettings.pyurls.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

-->

Reusability

Page 21: Moving from Django Apps to Services
Page 22: Moving from Django Apps to Services

REUSABILITY means faster features due to DRY (Don’t Repeat Yourself )

Page 23: Moving from Django Apps to Services

REUSABILITY means faster features due to DRY (Don’t Repeat Yourself )

REUSABILITY does not always mean SCALABILITY or MAINTAINABILITY

Page 24: Moving from Django Apps to Services

ProjectApp

A collection of configuration and apps for a particular Website.

A web application that does something. I.e. Weblog, Poll, Ticket system

(per Django Project)

Django

Page 25: Moving from Django Apps to Services

ProjectApp

A collection of configuration and apps for a particular Website.

A web application that does something. I.e. Weblog, Poll, Ticket system

Django

Service Method of communication over the web.Web APIs allow combination of multiple services

Page 26: Moving from Django Apps to Services
Page 27: Moving from Django Apps to Services

Tech imitate TeamsProject

App

App

App

Tickets

FAQ

FaqCreator

Company

Support

Knowledge Base

Page 28: Moving from Django Apps to Services

Support

Knowledge Base

Teams

Page 29: Moving from Django Apps to Services

App

App

Support

Knowledge Base

Teams Grow

Page 30: Moving from Django Apps to Services

App

App

Support

Knowledge Base

Billing

Teams Grow

Page 31: Moving from Django Apps to Services

App

App

Support

Knowledge Base

Billing

Marketing

Teams Grow

Page 32: Moving from Django Apps to Services

App

App

Support

Knowledge Base

Billing

Marketing

Analytics

Mobile

API

Front End

Social

Teams Grow

Page 33: Moving from Django Apps to Services

App

App

App

Support

Knowledge Base

Billing

Apps GrowMarketing

Analytics

Mobile

API

Front End

Social3 Apps

Page 34: Moving from Django Apps to Services

App

App

App

Support

Knowledge Base

Billing

Apps GrowApp

App

App

Marketing

Analytics

Mobile

App

App

App

API

Front End

Social9 Apps

Page 35: Moving from Django Apps to Services

Support

Knowledge Base

Billing

Apps GrowMarketing

Analytics

Mobile

API

Front End

Social

9 Apps

1 Codebase

Page 36: Moving from Django Apps to Services

SOA To the Rescue

Page 37: Moving from Django Apps to Services

SOA To the Rescue

Page 38: Moving from Django Apps to Services

SOA To the Rescue

Photo by Paul Downey (psd on flickr)

Page 39: Moving from Django Apps to Services

Defined contract for communicatingService

Page 40: Moving from Django Apps to Services

Defined contract for communicatingService

$ curl -O $FAQ_API/create/ -X “question=my\ question source=123”

Page 41: Moving from Django Apps to Services

In Python

Page 42: Moving from Django Apps to Services

In Python

data = {‘question’: “my question”,‘source’: 123}requests.POST(os.environ[‘FAQ_API’] + ‘/create/’, data=data)

Page 43: Moving from Django Apps to Services

More than just API

Page 44: Moving from Django Apps to Services

www.google.com

More than just API

Page 45: Moving from Django Apps to Services

www.google.commail.google.com

More than just API

Page 46: Moving from Django Apps to Services

www.google.commail.google.comcalendar.google.com

More than just API

Page 47: Moving from Django Apps to Services

www.google.commail.google.comcalendar.google.com..............google.com

More than just API

Page 48: Moving from Django Apps to Services

Types of Services

Page 49: Moving from Django Apps to Services

site

Types of Services

Page 50: Moving from Django Apps to Services

sitesubdomain

Types of Services

Page 51: Moving from Django Apps to Services

sitesubdomainAPI

Types of Services

Page 52: Moving from Django Apps to Services

sitesubdomainAPI - no auth required

Types of Services

Page 53: Moving from Django Apps to Services

sitesubdomainAPI - no auth required - API auth required

Types of Services

Page 54: Moving from Django Apps to Services

sitesubdomainAPI - no auth required - API auth required - user auth required

Types of Services

Page 55: Moving from Django Apps to Services

App

App

App

Support

Knowledge Base

Billing

Where to StartApp

App

App

Marketing

Analytics

Mobile

App

App

App

API

Front End

Social

Page 56: Moving from Django Apps to Services

App

App

Support

Knowledge Base

Billing

Where to StartAppMarketing

Analytics

Mobile App

API

Front End

Social

Page 57: Moving from Django Apps to Services
Page 58: Moving from Django Apps to Services
Page 59: Moving from Django Apps to Services
Page 60: Moving from Django Apps to Services

1 JavascriptMany pages

Page 61: Moving from Django Apps to Services
Page 62: Moving from Django Apps to Services
Page 63: Moving from Django Apps to Services
Page 64: Moving from Django Apps to Services

LA POSTA

Page 65: Moving from Django Apps to Services

Project

App

App

App

Tickets

FAQ

FaqCreator

Within Djangocd myproject && find .manage.pyrequirements.txtsettings.pyurls.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

Page 66: Moving from Django Apps to Services

Apps Depend on Other Apps

Page 67: Moving from Django Apps to Services

Apps Depend on Other Appsfaq creator

Page 68: Moving from Django Apps to Services

Apps Depend on Other Appsfaq creator

faq app

Page 69: Moving from Django Apps to Services

Apps Depend on Other Appsfaq creator

ticket

faq app

Page 70: Moving from Django Apps to Services

Apps Depend on Other Appsfaq creator

ticket

faq app

faq app

Page 71: Moving from Django Apps to Services

Apps Depend on Other Appsfaq creator

faq app version == 0.1

faq app version == 0.2ticket

Page 72: Moving from Django Apps to Services

Apps Depend on Other Appspip install faq==0.1pip install faq==0.2pip freezefaq==0.2

Page 73: Moving from Django Apps to Services

Apps Depend on Other Appsfaq creator

faq app version == 0.1

faq app version == 0.2ticket

Page 74: Moving from Django Apps to Services

Back to APIs

Page 75: Moving from Django Apps to Services

What’s a serviceProvider API_HOST= http://127.0.0.1

Page 76: Moving from Django Apps to Services

What’s a serviceProviderEndpoint

API_HOST= http://127.0.0.1

/v1/create/

Page 77: Moving from Django Apps to Services

What’s a serviceProviderEndpoint

API_HOST= http://127.0.0.1

/v1/create/

Contract {‘question’: ‘foo bar’,‘source’: 123}

Page 78: Moving from Django Apps to Services

App

Page 79: Moving from Django Apps to Services

AppModelsViewsURLs

Page 80: Moving from Django Apps to Services

Service

AppModelsViewsURLs

Provider Endpoint Contract

Page 81: Moving from Django Apps to Services

A SERVICE means REUSABILITY and enables SCALABILITY and MAINTAINABILITY

Page 82: Moving from Django Apps to Services

Where to start

Page 83: Moving from Django Apps to Services

Where to start1. If you’re monolithic, break up the apps first

Page 84: Moving from Django Apps to Services

Where to start1. If you’re monolithic, break up the apps first2. Port something that doesn’t require user

Page 85: Moving from Django Apps to Services

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

Page 86: Moving from Django Apps to Services

Porting an Appmodels.py

class 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

Page 87: Moving from Django Apps to Services

Porting an App

faqcreator/views.py

from faq.models import faq

i = Faq(title=‘foo’, description=‘bar’, solution=’la posta’)i.save()

Page 88: Moving from Django Apps to Services

Turn it into an API

Page 89: Moving from Django Apps to Services

Turn it into an API1. pip install django-tastypie

Page 90: Moving from Django Apps to Services

Turn it into an API1. pip install django-tastypie2. add tastypie to INSTALLED_APPS

Page 91: Moving from Django Apps to Services

Turn it into an API1. pip install django-tastypie2. add tastypie to INSTALLED_APPS3. define your APIs

Page 92: Moving from Django Apps to Services

Create your APIfaq/api.py

from tastypie.resources import ModelResourcefrom faq.models import Faqfrom django.contrib.auth.models import Userfrom tastypie.authentication import BasicAuthentication, DjangoAuthorizationfrom tastypie.authorization import Authorization

class 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)

Page 93: Moving from Django Apps to Services

Create your APIapi.py

class 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)

Page 94: Moving from Django Apps to Services

Create your APIapi.py

class 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)

Page 95: Moving from Django Apps to Services

Create your APIapi.py

class 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)

Page 96: Moving from Django Apps to Services

Create your APIapi.py

class 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)

Page 97: Moving from Django Apps to Services

Create your APIapi.py

class 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)

Page 98: Moving from Django Apps to Services

Create your APIapi.py

class 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)

Page 99: Moving from Django Apps to Services

Create your APIurls.py

from faq.api import FaqResourcefrom tastypie.api import Api

v1_api = Api(api_name='v1')v1_api.register(FaqResource())

urlpatterns = patterns('', url(r'^api/', include(v1_api.urls)),)

Page 100: Moving from Django Apps to Services

curl -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 your API

Page 101: Moving from Django Apps to Services

Use it in Python

Page 102: Moving from Django Apps to Services

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'))

Page 103: Moving from Django Apps to Services

Version Bump

Page 104: Moving from Django Apps to Services

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'))

Page 105: Moving from Django Apps to Services

Version Bump

Page 106: Moving from Django Apps to Services

data = { '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

Page 107: Moving from Django Apps to Services

In our Applicationfaq_creator/views.py

ticket/views.py

Page 108: Moving from Django Apps to Services

r = requests.post(os.environ[‘FAQ_API’] + "api/v2/faq/", data=data, auth=('admin', 'testing'))

In our Application

r = requests.post(os.environ[‘FAQ_API’] + "api/v1/faq/", data=data, auth=('admin', 'testing'))

faq_creator/views.py

ticket/views.py

Page 109: Moving from Django Apps to Services

cd myproject && find .manage.pyrequirements.txtsettings.pyurls.py

cat myproject/requirements.txtfaq==0.1faqcreator==0.1 tickets==0.1

cd myproject && find .manage.pyrequirements.txtsettings.pyurls.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

-->

Reusability

Page 110: Moving from Django Apps to Services

cd myproject && find .

manage.pyrequirements.txtsettings.pyurls.py

cat myproject/requirements.txt

faq==0.1faqcreator==0.1 tickets==0.1

-->

Maintainability/Scalability/Agilityls projectsfaq-servicemyproject

cd faq-service && find .manage.pyrequirements.txtsettings.pyurls.py

cd myproject && find .manage.pyrequirements.txtsettings.pyurls.py

cat myproject/requirements.txtfaqcreator==0.1 tickets==0.1

Page 111: Moving from Django Apps to Services

Maintainability/Scalability/Agility

Page 112: Moving from Django Apps to Services

Maintainability/Scalability/AgilityFaq Project

- Its own Django project- 1 Django app- Own database- Own deployment

Page 113: Moving from Django Apps to Services

Maintainability/Scalability/AgilityFaq Project

- Its own Django project- 1 Django app- Own database- Own deployment

My Project- Contained Django Project- 2 Django apps- Own database- Own deployment

Page 114: Moving from Django Apps to Services

Take aways

Page 115: Moving from Django Apps to Services

Take aways1. Start non-critical (Cheat)2. Create services where theres app reuse3. Create services where theres pain4. Start small

Page 116: Moving from Django Apps to Services

Others

Page 117: Moving from Django Apps to Services

Others

1. Expect APIs to fail2. Flask is great for APIs3. Make it easy to setup/test