Django Apps to Services
Craig Kerstiens   @craigkerstiens work at @heroku
DjangoProject   A collection of configuration and apps for a particular Website.                                          ...
DjangoProject   A collection of configuration and apps for a particular Website.App       A web application that does some...
TableTable                   Table                                Table                        Table           Table      ...
TableTable                   Table                                Table                        Table           Table      ...
TableTable                   Table                                Table                                   p               ...
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 ...
Monolithic Monster $ ls mysite                  $ wc -l models.py models.py                          2557 models.py views....
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            ...
Reusability
cd myproject && find .                         Reusability
cd myproject && find .                          Reusability manage.py requirements.txt settings.py urls.py ./faq/admin.py ...
cd myproject && find .                          Reusability                                   cd myproject && find . manag...
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 MAINTAI...
DjangoProject   A collection of configuration and apps for a particular Website.App       A web application that does some...
DjangoProject   A collection of configuration and apps for a particular Website.App       A web application that does some...
Tech imitate TeamsProject          Company   Tickets     App               Support     FAQ     App            Knowledge Ba...
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         ...
Apps Grow     App   Support         Marketing      API          p  s     App     A  pKnowledge Base     Analytics   Front ...
Apps Grow     App   Support                      p                    App                        s                     Mar...
Apps Grow   Support                      p s                     Marketing      API                   Ap        seKnowledg...
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                                  ...
Where to Start     App   Support              App                     Marketing       API     AppKnowledge Base       Anal...
1 JavascriptMany pages
LA POSTA
Within Django                cd myproject && find .                 manage.pyProject          requirements.txt            ...
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...
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...
Porting an App                     models.pyclass Faq(models.Model):  title = models.CharField(max_length=100)  source = m...
Porting an App             faqcreator/views.pyfrom faq.models import faqi = Faq(title=‘foo’, description=‘bar’, solution=’...
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   ...
Create your API                             api.pyclass FaqResource(ModelResource):  class Meta:     queryset = Faq.object...
Create your API                             api.pyclass FaqResource(ModelResource):  class Meta:     queryset = Faq.object...
Create your API                             api.pyclass FaqResource(ModelResource):  class Meta:     queryset = Faq.object...
Create your API                             api.pyclass FaqResource(ModelResource):  class Meta:     queryset = Faq.object...
Create your API                             api.pyclass FaqResource(ModelResource):  class Meta:     queryset = Faq.object...
Create your API                             api.pyclass FaqResource(ModelResource):  class Meta:     queryset = Faq.object...
Create your API                         urls.pyfrom faq.api import FaqResourcefrom tastypie.api import Apiv1_api = Api(api...
Use your APIcurl -H "Content-Type: application/json"     --user admin:testing     -X POST     --data       {"title": "New ...
Use it in Python
Use it in Pythondata = {  title: New FAQ,  source: 1,  description: foo,  solution: bar}r = requests.post(os.environ[‘FAQ_...
Version Bump
Version Bumpdata = {  title: New FAQ,  source: 1,  description: foo,  solution: bar,  related: [123, 456]}r = requests.pos...
Version Bump
Version Bumpdata = {  title: New FAQ,  source: 1,  description: foo,  solution: bar,  related: [123, 456]}r = requests.pos...
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,  aut...
cd myproject && find .                          Reusability                                   cd myproject && find . manag...
Maintainability/Scalability/Agilitycd myproject && find .                 ls projects manage.py                           ...
Maintainability/Scalability/Agility
Maintainability/Scalability/Agility                  Faq Project                   - Its own Django project               ...
Maintainability/Scalability/AgilityMy Project                    Faq Project - Contained Django Project    - Its own Djang...
Take aways
Take aways1. Start non-critical (Cheat)2. Create services where theres app reuse3. Create services where theres pain4. Sta...
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/cr...
Moving from Django Apps to Services
Moving from Django Apps to Services
Moving from Django Apps to Services
Moving from Django Apps to Services
Moving from Django Apps to Services
Moving from Django Apps to Services
Moving from Django Apps to Services
Moving from Django Apps to Services
Upcoming SlideShare
Loading in...5
×

Moving from Django Apps to Services

1,130

Published on

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

0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,130
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
27
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

Moving from Django Apps to Services

  1. 1. Django Apps to Services
  2. 2. Craig Kerstiens @craigkerstiens work at @heroku
  3. 3. DjangoProject A collection of configuration and apps for a particular Website. (per Django Project)
  4. 4. 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)
  5. 5. TableTable Table Table Table Table Table Table Table TableTable Table Table TableTable Table Table Table Table Table Table
  6. 6. TableTable Table Table Table Table Table Table Table TableTable Table Table TableTable Table Table Table Table Table Table
  7. 7. TableTable Table Table p Table Table Table p Table A Table TableTable Table Table TableTable Table Table Table Table Table Table
  8. 8. Monolithic Monster
  9. 9. Monolithic Monster$ ls mysitemodels.pyviews.pyforms.pyadmin.py
  10. 10. Monolithic Monster$ ls mysite $ wc -l models.pymodels.py 2557 models.pyviews.py $ wc -l view.spyforms.py 14241 views.pyadmin.py
  11. 11. 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
  12. 12. Within Django
  13. 13. Within DjangoProject
  14. 14. Within DjangoProject App App App
  15. 15. Within DjangoProject Tickets App FAQ App FaqCreator App
  16. 16. 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
  17. 17. Reusability
  18. 18. cd myproject && find . Reusability
  19. 19. 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
  20. 20. 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
  21. 21. REUSABILITY means faster features due to DRY(Don’t Repeat Yourself )
  22. 22. REUSABILITY means faster features due to DRY(Don’t Repeat Yourself )REUSABILITY does not always mean SCALABILITYor MAINTAINABILITY
  23. 23. 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)
  24. 24. 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
  25. 25. Tech imitate TeamsProject Company Tickets App Support FAQ App Knowledge Base FaqCreator App
  26. 26. Teams SupportKnowledge Base
  27. 27. Teams Grow App Support AppKnowledge Base
  28. 28. Teams Grow App Support AppKnowledge Base Billing
  29. 29. Teams Grow App Support Marketing AppKnowledge Base Billing
  30. 30. Teams Grow App Support Marketing API AppKnowledge Base Analytics Front End Billing Mobile Social
  31. 31. Apps Grow App Support Marketing API p s App A pKnowledge Base Analytics Front End3 App Billing Mobile Social
  32. 32. 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
  33. 33. Apps Grow Support p s Marketing API Ap seKnowledge Base 9 deb a Analytics Front End Billing C o Mobile Social 1
  34. 34. SOA To the Rescue
  35. 35. SOA To the Rescue
  36. 36. SOA To the Rescue Photo by Paul Downey (psd on flickr)
  37. 37. ServiceDefined contract for communicating
  38. 38. ServiceDefined contract for communicating$ curl -O $FAQ_API/create/ -X “question=my question source=123”
  39. 39. In Python
  40. 40. In Pythondata = { ‘question’: “my question”, ‘source’: 123}requests.POST(os.environ[‘FAQ_API’] + ‘/create/’, data=data)
  41. 41. More than just API
  42. 42. More than just APIwww.google.com
  43. 43. More than just APIwww.google.commail.google.com
  44. 44. More than just APIwww.google.commail.google.comcalendar.google.com
  45. 45. More than just APIwww.google.commail.google.comcalendar.google.com..............google.com
  46. 46. Types of Services
  47. 47. Types of Servicessite
  48. 48. Types of Servicessitesubdomain
  49. 49. Types of ServicessitesubdomainAPI
  50. 50. Types of ServicessitesubdomainAPI - no auth required
  51. 51. Types of ServicessitesubdomainAPI - no auth required - API auth required
  52. 52. Types of ServicessitesubdomainAPI - no auth required - API auth required - user auth required
  53. 53. Where to Start App Support App Marketing App API AppKnowledge Base App Analytics App Front End App Billing App Mobile App Social
  54. 54. Where to Start App Support App Marketing API AppKnowledge Base Analytics Front End Billing Mobile App Social
  55. 55. 1 JavascriptMany pages
  56. 56. LA POSTA
  57. 57. 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
  58. 58. Apps Depend on Other Apps
  59. 59. Apps Depend on Other Appsfaq creator
  60. 60. Apps Depend on Other Appsfaq creator faq app
  61. 61. Apps Depend on Other Appsfaq creator faq appticket
  62. 62. Apps Depend on Other Appsfaq creator faq appticket faq app
  63. 63. Apps Depend on Other Appsfaq creator faq app version == 0.1ticket faq app version == 0.2
  64. 64. Apps Depend on Other Appspip install faq==0.1pip install faq==0.2pip freezefaq==0.2
  65. 65. Apps Depend on Other Appsfaq creator faq app version == 0.1ticket faq app version == 0.2
  66. 66. Back to APIs
  67. 67. What’s a serviceProvider API_HOST= http://127.0.0.1
  68. 68. What’s a serviceProvider API_HOST= http://127.0.0.1Endpoint /v1/create/
  69. 69. What’s a serviceProvider API_HOST= http://127.0.0.1Endpoint /v1/create/Contract { ‘question’: ‘foo bar’, ‘source’: 123 }
  70. 70. App
  71. 71. AppURLs Views Models
  72. 72. AppURLs Views Models ServiceProvider Endpoint Contract
  73. 73. A SERVICE means REUSABILITYand enables SCALABILITY andMAINTAINABILITY
  74. 74. Where to start
  75. 75. Where to start1. If you’re monolithic, break up the apps first
  76. 76. Where to start1. If you’re monolithic, break up the apps first2. Port something that doesn’t require user
  77. 77. 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
  78. 78. 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
  79. 79. Porting an App faqcreator/views.pyfrom faq.models import faqi = Faq(title=‘foo’, description=‘bar’, solution=’la posta’)i.save()
  80. 80. Turn it into an API
  81. 81. Turn it into an API1. pip install django-tastypie
  82. 82. Turn it into an API1. pip install django-tastypie2. add tastypie to INSTALLED_APPS
  83. 83. Turn it into an API1. pip install django-tastypie2. add tastypie to INSTALLED_APPS3. define your APIs
  84. 84. 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)
  85. 85. 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)
  86. 86. 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)
  87. 87. 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)
  88. 88. 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)
  89. 89. 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)
  90. 90. 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)
  91. 91. 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)),)
  92. 92. 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/
  93. 93. Use it in Python
  94. 94. 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))
  95. 95. Version Bump
  96. 96. 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))
  97. 97. Version Bump
  98. 98. 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))
  99. 99. In our Applicationfaq_creator/views.py ticket/views.py
  100. 100. 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))
  101. 101. 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
  102. 102. 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
  103. 103. Maintainability/Scalability/Agility
  104. 104. Maintainability/Scalability/Agility Faq Project - Its own Django project - 1 Django app - Own database - Own deployment
  105. 105. 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
  106. 106. Take aways
  107. 107. Take aways1. Start non-critical (Cheat)2. Create services where theres app reuse3. Create services where theres pain4. Start small
  108. 108. Others
  109. 109. Others1. Expect APIs to fail2. Flask is great for APIs3. Make it easy to setup/test
  110. 110. Fin. Resourceshttp://www.craigkerstiens.comhttp://bit.ly/djangoappstoservices/http://www.12factor.nethttp://github.com/craigkerstiens/
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×