Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Getting Rest With Webmachine

29,468 views

Published on

Learn how to use webmachine to build a RESTful web application in Erlang.

Published in: Technology, News & Politics
  • good presentation !
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

Getting Rest With Webmachine

  1. 1. Getting Some REST with webmachine Kevin A. Smith
  2. 2. What is webmachine?
  3. 3. Framework
  4. 4. Framework
  5. 5. Toolkit
  6. 6. A toolkit for building RESTful HTTP resources
  7. 7. What is REST?
  8. 8. Style not a standard
  9. 9. Resources == URLs
  10. 10. http://localhost:8000/hello_world
  11. 11. http://foo.com/hr/emp/123
  12. 12. GET POST DELETE PUT
  13. 13. REST is the shape of the web
  14. 14. -module(hello_world_resource). -export([init/1, to_html/2]). -include_lib("webmachine/include/webmachine.hrl"). init([]) -> {ok, "Hello, world"}. to_html(Req, State) -> Output = io_lib:format(“<html><body>~s</body></html>”, [State]), {Output, Req, State}.
  15. 15. -module(hello_world_resource). -export([init/1, to_html/2]). -include_lib("webmachine/include/webmachine.hrl"). init([]) -> {ok, "Hello, world"}. to_html(Req, State) -> Output = io_lib:format(“<html><body>~s</body></html>”, [State]), {Output, Req, State}.
  16. 16. -module(hello_world_resource). -export([init/1, to_html/2]). -include_lib("webmachine/include/webmachine.hrl"). init([]) -> {ok, "Hello, world"}. to_html(Req, State) -> Output = io_lib:format(“<html><body>~s</body></html>”, [State]), {Output, Req, State}.
  17. 17. -module(hello_world_resource). -export([init/1, to_html/2]). -include_lib("webmachine/include/webmachine.hrl"). init([]) -> {ok, "Hello, world"}. to_html(Req, State) -> Output = io_lib:format(“<html><body>~s</body></html>”, [State]), {Output, Req, State}.
  18. 18. -module(hello_world_resource). -export([init/1, to_html/2]). -include_lib("webmachine/include/webmachine.hrl"). init([]) -> {ok, "Hello, world"}. to_html(Req, State) -> Output = io_lib:format(“<html><body>~s</body></html>”, [State]), {Output, Req, State}.
  19. 19. A toolkit for easily building RESTful HTTP resources
  20. 20. GET /test HTTP/1.1 Host: localhost:8000 User-Agent: Mozilla/5.0 Accept: text/html;q=0.9,*/*;q=0.8 Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: UTF-8,* Keep-Alive: 300 Connection: keep-alive HTTP/1.x 200 OK Server: MochiWeb/1.1 WebMachine/1.3 Date: Mon, 22 Jun 2009 02:27:46 GMT Content-Type: text/html Content-Length: 78
  21. 21. -module(hello_world_resource). -export([init/1, to_html/2]). -export([generate_etag/2]). -include_lib("webmachine/include/webmachine.hrl"). init([]) -> {ok, "Hello, world"}. to_html(Req, State) -> Output = io_lib:format(“<html><body>~s</body></html>”, [State]), {Output, Req, State}. generate_etag(Req, State) -> {mochihex:to_hex(crypto:md5(State)), Req, State}.
  22. 22. GET /test HTTP/1.1 Host: localhost:8000 User-Agent: Mozilla/5.0 Accept: text/html;q=0.9,*/*;q=0.8 Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: UTF-8,* Keep-Alive: 300 Connection: keep-alive HTTP/1.x 200 OK Server: MochiWeb/1.1 WebMachine/1.3 Etag: bc6e6f16b8a077ef5fbc8d59d0b931b9 Date: Mon, 22 Jun 2009 02:29:46 GMT Content-Type: text/html Content-Length: 78
  23. 23. GET /test HTTP/1.1 Host: localhost:8000 . . . If-None-Match: bc6e6f16b8a077ef5fbc8d59d0b931b9 HTTP/1.x 304 Not Modified Server: MochiWeb/1.1 WebMachine/1.3 Etag: bc6e6f16b8a077ef5fbc8d59d0b931b9 Date: Mon, 22 Jun 2009 02:30:00 GMT
  24. 24. -module(hello_world_resource). -export([init/1, to_html/2]). -export([generate_etag/2, encodings_provided/2]). -include_lib("webmachine/include/webmachine.hrl"). init([]) -> {ok, "Hello, world"}. to_html(Req, State) -> Output = io_lib:format(“<html><body>~s</body></html>”, [State]), {Out, Req, State}. generate_etag(Req, State) -> {mochihex:to_hex(crypto:md5(State)), Req, State}. encodings_provided(Req, State) -> {[{"gzip", fun(X) -> zlib:gzip(X) end}], Req, State}.
  25. 25. GET /test HTTP/1.1 Host: localhost:8000 . . . Accept-Encoding: gzip,deflate HTTP/1.x 200 OK Server: MochiWeb/1.1 WebMachine/1.3 Etag: bc6e6f16b8a077ef5fbc8d59d0b931b9 Date: Mon, 22 Jun 2009 02:46:57 GMT Content-Type: text/html Content-Length: 71 Content-Encoding: gzip
  26. 26. HTTP Is Hard
  27. 27. PUT ERROR CODES vs. PO ST O N I TI AT ENC O ODI NEG N GS T T EN IDEMPOTENCY N N IO C O IR AT X P STREA E MING T OVE T EN ET RLOA O N G DED C A L POS O N Ts I TI ND CO
  28. 28. Request Routing
  29. 29. http://foo.com/items {["items"], grocery_item_resource, []}. URL path Resource module Init params
  30. 30. http://foo.com/items/chocolate {["items", item], grocery_item_resource, []}. URL path URL variable Resource module Init params
  31. 31. GET
  32. 32. -module(hello_world_resource). -export([init/1,to_html/2]). -include_lib("webmachine/include/webmachine.hrl"). init([]) -> {ok, "Hello, world"}. to_html(Req, State) -> Output = io_lib:format(“<html><body>~s</body></html>”, [State]), {Output, Req, State}.
  33. 33. Must be idempotent
  34. 34. PUT
  35. 35. -module(grocery_list_resource). -export([init/1,allowed_methods/2]). -export([content_types_accepted/2,from_json/2]). -include_lib("webmachine/include/webmachine.hrl"). init([]) -> {ok, []}. allowed_methods(Req, State) -> {[‘PUT’], Req, State}. content_types_accepted(Req, State) -> {[{“application/json”, from_json}], Req, State}. from_json(Req, State) -> %% Create/update logic here
  36. 36. DELETE
  37. 37. -module(grocery_list_resource). -export([init/1,allowed_methods/2]). -export([delete_resource/2]). -include_lib("webmachine/include/webmachine.hrl"). init([]) -> {ok, []}. allowed_methods(Req, State) -> {[‘DELETE’], Req, State}. delete_resource(Req, State) -> %% Deletion logic here
  38. 38. POST
  39. 39. Hmmmm
  40. 40. Problems with POST
  41. 41. Problems with POST • Overloaded semantics
  42. 42. Problems with POST • Overloaded semantics • Create or update?
  43. 43. Creation via POST •allowed_methods/2 •post_is_create/2 •create_path/2 •content_types_accepted/2 • handler function
  44. 44. Update via POST •allowed_methods/2 •content_types_accepted/2 • handler function
  45. 45. CODE TIME
  46. 46. HTTP Request Access
  47. 47. HTTP Request • “Wrapped” mochiweb request • Separate process for each request • Direct access to: request/response headers, response body, etc.
  48. 48. Other Cool Stuff • Graphical request debugging • Streaming requests and responses • File uploads
  49. 49. webmachine source: http://bitbucket.org/justin/webmachine Slides and demo code: http://github.com/kevsmith/erlang_factory/tree/master

×