{"id":3264,"date":"2013-02-22T15:42:12","date_gmt":"2013-02-22T23:42:12","guid":{"rendered":"http:\/\/blog.mozilla.org\/webdev\/?p=3264"},"modified":"2013-03-08T12:53:19","modified_gmt":"2013-03-08T20:53:19","slug":"the-restful-marketplace","status":"publish","type":"post","link":"https:\/\/blog.mozilla.org\/webdev\/2013\/02\/22\/the-restful-marketplace\/","title":{"rendered":"The restful Marketplace"},"content":{"rendered":"<p>While the <a href=\"https:\/\/marketplace.firefox.com\">Firefox Marketplace<\/a> is being built, we are starting to make some fundamental changes in the way the Marketplace is constructed behind the scenes. In the beginning there was one big <a href=\"http:\/\/djangoproject.com\">Django<\/a> site that served all the requests back to the users. <\/p>\n<p>Over the course of the last few months that has changed to being a smaller number of services that provide APIs to each other. We&#8217;ve got separate services for <a href=\"https:\/\/github.com\/mozilla\/solitude\">payments<\/a> (<a href=\"https:\/\/github.com\/mozilla\/webpay\">and this<\/a>), <a href=\"htts:\/\/github.com\/mozilla\/monolith\">statistics<\/a> (<a href=\"https:\/\/github.com\/mozilla\/monolith-aggregator\">and this<\/a>) and a new <a href=\"https:\/\/github.com\/mozilla\/fireplace\">front end client<\/a> and plans for more. The main communication mechanism between them is going to be REST APIs.<\/p>\n<p>For REST APIs in Django we are currently using <a href=\"https:\/\/github.com\/toastdriven\/django-tastypie\">Tastypie<\/a>, which does a pretty good job of doing a lot of things you&#8217;d need. There are a few frustrations with Tastypie and going forward I&#8217;m extremely tempted by <a href=\"https:\/\/github.com\/mozilla-services\/cornice\">Cornice<\/a>, which we currently use for statistics.<\/p>\n<p>When you ask people about consuming REST APIs in Python, lots of people tell me &#8220;we just use <a href=\"http:\/\/docs.python-requests.org\/en\/latest\/\">requests<\/a>&#8220;. Requests is a great library for making HTTP calls, but when you are developing against a REST API having all the overhead of coping with HTTP is a bit much. Coping with client errors versus HTTP errors, understanding the error responses, scaling and failover and generally coping with an imperfect world.<\/p>\n<p>So we took <a href=\"http:\/\/slumber.readthedocs.org\/en\/latest\/\">slumber<\/a> and wrapped that in our our library called <a href=\"https:\/\/curling.readthedocs.org\/en\/latest\/\">curling<\/a>. Curling is a wrapper that makes some assumptions about the server and the client. It provides us one entry point for all our REST APIs and a place to have consistency on the client side. Below I get a timestamp on a transaction using requests.<\/p>\n<p><script src=\"https:\/\/gist.github.com\/andymckay\/5017272.js\"><\/script><\/p>\n<p>However in the curling example it will check that one and only one result is returned (and raise meaningful errors if it didn&#8217;t) and correctly raise a meaningful error based on the HTTP response.<\/p>\n<p><script src=\"https:\/\/gist.github.com\/andymckay\/5017357.js\"><\/script><\/p>\n<p>The result is code that is easier to write and read, but it is still relatively close to the metal of just being a REST API without being as simple as just HTTP requests or as complicated as a Web Services and SOAP stack.<\/p>\n<p>As an extra bonus curling has a command line API that fills some HTTP headers out for you, syntax highlights output and the like. As a bonus, if you are calling a Django server in debug mode, rather than spew lines of HTML to the screen &#8211; it will write the HTML to a file and open a browser to the file.<\/p>\n<p><a href=\"http:\/\/blog.mozilla.org\/webdev\/files\/2013\/02\/Screen-Shot-2013-02-22-at-3.16.52-PM.png\"><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/blog.mozilla.org\/webdev\/files\/2013\/02\/Screen-Shot-2013-02-22-at-3.16.52-PM.png\" alt=\"Screen Shot 2013-02-22 at 3.16.52 PM\" width=\"642\" height=\"307\" class=\"alignnone size-full wp-image-3269\" srcset=\"https:\/\/blog.mozilla.org\/webdev\/files\/2013\/02\/Screen-Shot-2013-02-22-at-3.16.52-PM.png 642w, https:\/\/blog.mozilla.org\/webdev\/files\/2013\/02\/Screen-Shot-2013-02-22-at-3.16.52-PM-300x143.png 300w\" sizes=\"(max-width: 642px) 100vw, 642px\" \/><\/a><\/p>\n<p>These APIs are open and growing rapidly. You can find documentation on them on each project, but the main one to follow is in <a href=\"http:\/\/zamboni.readthedocs.org\/en\/latest\/topics\/api.html\">zamboni<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>While the Firefox Marketplace is being built, we are starting to make some fundamental changes in the way the Marketplace is constructed behind the scenes. In the beginning there was one big Django site that served all the requests back &hellip; <a class=\"go\" href=\"https:\/\/blog.mozilla.org\/webdev\/2013\/02\/22\/the-restful-marketplace\/\">Continue reading<\/a><\/p>\n","protected":false},"author":271,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[19566,288],"tags":[553],"coauthors":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v22.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>The restful Marketplace - Mozilla Web Development<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blog.mozilla.org\/webdev\/2013\/02\/22\/the-restful-marketplace\/\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Andy McKay\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"2 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.mozilla.org\/webdev\/2013\/02\/22\/the-restful-marketplace\/\",\"url\":\"https:\/\/blog.mozilla.org\/webdev\/2013\/02\/22\/the-restful-marketplace\/\",\"name\":\"The restful Marketplace - Mozilla Web Development\",\"isPartOf\":{\"@id\":\"https:\/\/blog.mozilla.org\/webdev\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/blog.mozilla.org\/webdev\/2013\/02\/22\/the-restful-marketplace\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/blog.mozilla.org\/webdev\/2013\/02\/22\/the-restful-marketplace\/#primaryimage\"},\"thumbnailUrl\":\"http:\/\/blog.mozilla.org\/webdev\/files\/2013\/02\/Screen-Shot-2013-02-22-at-3.16.52-PM.png\",\"datePublished\":\"2013-02-22T23:42:12+00:00\",\"dateModified\":\"2013-03-08T20:53:19+00:00\",\"author\":{\"@id\":\"https:\/\/blog.mozilla.org\/webdev\/#\/schema\/person\/7e1881db0e8a23a4a06695f8a0efd6b8\"},\"breadcrumb\":{\"@id\":\"https:\/\/blog.mozilla.org\/webdev\/2013\/02\/22\/the-restful-marketplace\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.mozilla.org\/webdev\/2013\/02\/22\/the-restful-marketplace\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blog.mozilla.org\/webdev\/2013\/02\/22\/the-restful-marketplace\/#primaryimage\",\"url\":\"http:\/\/blog.mozilla.org\/webdev\/files\/2013\/02\/Screen-Shot-2013-02-22-at-3.16.52-PM.png\",\"contentUrl\":\"http:\/\/blog.mozilla.org\/webdev\/files\/2013\/02\/Screen-Shot-2013-02-22-at-3.16.52-PM.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.mozilla.org\/webdev\/2013\/02\/22\/the-restful-marketplace\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/blog.mozilla.org\/webdev\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"The restful Marketplace\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog.mozilla.org\/webdev\/#website\",\"url\":\"https:\/\/blog.mozilla.org\/webdev\/\",\"name\":\"Mozilla Web Development\",\"description\":\"For make benefit of glorious tubes\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog.mozilla.org\/webdev\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/blog.mozilla.org\/webdev\/#\/schema\/person\/7e1881db0e8a23a4a06695f8a0efd6b8\",\"name\":\"Andy McKay\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blog.mozilla.org\/webdev\/#\/schema\/person\/image\/96eb032e0f9fa78d076a49a55bf3cd09\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/ad304e7a7d4f6fba05a81b10810fe6fd?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/ad304e7a7d4f6fba05a81b10810fe6fd?s=96&d=mm&r=g\",\"caption\":\"Andy McKay\"},\"description\":\"Andy is an Engineering Manager at Mozilla. As a Canadian he tweets and blogs about curling, skiing, politics, maple syrup, bears and all things from the great white north.\",\"sameAs\":[\"http:\/\/mckay.pub\",\"https:\/\/x.com\/andymckay\"],\"url\":\"https:\/\/blog.mozilla.org\/webdev\/author\/amckaymozilla-com\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"The restful Marketplace - Mozilla Web Development","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blog.mozilla.org\/webdev\/2013\/02\/22\/the-restful-marketplace\/","twitter_misc":{"Written by":"Andy McKay","Est. reading time":"2 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/blog.mozilla.org\/webdev\/2013\/02\/22\/the-restful-marketplace\/","url":"https:\/\/blog.mozilla.org\/webdev\/2013\/02\/22\/the-restful-marketplace\/","name":"The restful Marketplace - Mozilla Web Development","isPartOf":{"@id":"https:\/\/blog.mozilla.org\/webdev\/#website"},"primaryImageOfPage":{"@id":"https:\/\/blog.mozilla.org\/webdev\/2013\/02\/22\/the-restful-marketplace\/#primaryimage"},"image":{"@id":"https:\/\/blog.mozilla.org\/webdev\/2013\/02\/22\/the-restful-marketplace\/#primaryimage"},"thumbnailUrl":"http:\/\/blog.mozilla.org\/webdev\/files\/2013\/02\/Screen-Shot-2013-02-22-at-3.16.52-PM.png","datePublished":"2013-02-22T23:42:12+00:00","dateModified":"2013-03-08T20:53:19+00:00","author":{"@id":"https:\/\/blog.mozilla.org\/webdev\/#\/schema\/person\/7e1881db0e8a23a4a06695f8a0efd6b8"},"breadcrumb":{"@id":"https:\/\/blog.mozilla.org\/webdev\/2013\/02\/22\/the-restful-marketplace\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.mozilla.org\/webdev\/2013\/02\/22\/the-restful-marketplace\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blog.mozilla.org\/webdev\/2013\/02\/22\/the-restful-marketplace\/#primaryimage","url":"http:\/\/blog.mozilla.org\/webdev\/files\/2013\/02\/Screen-Shot-2013-02-22-at-3.16.52-PM.png","contentUrl":"http:\/\/blog.mozilla.org\/webdev\/files\/2013\/02\/Screen-Shot-2013-02-22-at-3.16.52-PM.png"},{"@type":"BreadcrumbList","@id":"https:\/\/blog.mozilla.org\/webdev\/2013\/02\/22\/the-restful-marketplace\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blog.mozilla.org\/webdev\/"},{"@type":"ListItem","position":2,"name":"The restful Marketplace"}]},{"@type":"WebSite","@id":"https:\/\/blog.mozilla.org\/webdev\/#website","url":"https:\/\/blog.mozilla.org\/webdev\/","name":"Mozilla Web Development","description":"For make benefit of glorious tubes","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog.mozilla.org\/webdev\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/blog.mozilla.org\/webdev\/#\/schema\/person\/7e1881db0e8a23a4a06695f8a0efd6b8","name":"Andy McKay","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blog.mozilla.org\/webdev\/#\/schema\/person\/image\/96eb032e0f9fa78d076a49a55bf3cd09","url":"https:\/\/secure.gravatar.com\/avatar\/ad304e7a7d4f6fba05a81b10810fe6fd?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/ad304e7a7d4f6fba05a81b10810fe6fd?s=96&d=mm&r=g","caption":"Andy McKay"},"description":"Andy is an Engineering Manager at Mozilla. As a Canadian he tweets and blogs about curling, skiing, politics, maple syrup, bears and all things from the great white north.","sameAs":["http:\/\/mckay.pub","https:\/\/x.com\/andymckay"],"url":"https:\/\/blog.mozilla.org\/webdev\/author\/amckaymozilla-com\/"}]}},"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/blog.mozilla.org\/webdev\/wp-json\/wp\/v2\/posts\/3264"}],"collection":[{"href":"https:\/\/blog.mozilla.org\/webdev\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.mozilla.org\/webdev\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.mozilla.org\/webdev\/wp-json\/wp\/v2\/users\/271"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.mozilla.org\/webdev\/wp-json\/wp\/v2\/comments?post=3264"}],"version-history":[{"count":0,"href":"https:\/\/blog.mozilla.org\/webdev\/wp-json\/wp\/v2\/posts\/3264\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.mozilla.org\/webdev\/wp-json\/wp\/v2\/media?parent=3264"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.mozilla.org\/webdev\/wp-json\/wp\/v2\/categories?post=3264"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.mozilla.org\/webdev\/wp-json\/wp\/v2\/tags?post=3264"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/blog.mozilla.org\/webdev\/wp-json\/wp\/v2\/coauthors?post=3264"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}