JSON - Schmason

JSON - Schmason

Using Rails for building Web APIs

B5b39c8f21b5bb1ab97852ed32c888ab?s=128

Jan Krutisch

October 16, 2012
Tweet

Transcript

  1. JSON - Schmason Using Rails for building Web APIs WebTech

    Conference 2012 Jan Krutisch http://jan.krutisch.de/ Dienstag, 16. Oktober 12
  2. JSON - Schmason Using Rails for building Web APIs WebTech

    Conference 2012 Jan Krutisch http://jan.krutisch.de/ Dienstag, 16. Oktober 12
  3. Designing Building Testing Dienstag, 16. Oktober 12

  4. Assumptions Dienstag, 16. Oktober 12

  5. JSON Dienstag, 16. Oktober 12

  6. !XML Dienstag, 16. Oktober 12

  7. Designing Dienstag, 16. Oktober 12

  8. REST Dienstag, 16. Oktober 12

  9. REpresenational State Transfer Dienstag, 16. Oktober 12

  10. „Pragmatic REST“ Dienstag, 16. Oktober 12

  11. POST /books.json GET /books.json GET /books/1.json PUT /books/1.json DELETE /books/1.json

    Dienstag, 16. Oktober 12
  12. POST /books/1/comments.json GET /books/1/comments.json GET /books/1/comments/1.json PUT /books/1/comments/1.json DELETE /books/1/comments/1.json

    Dienstag, 16. Oktober 12
  13. Hypermedia As The Engine Of Application State Dienstag, 16. Oktober

    12
  14. HATEOAS Dienstag, 16. Oktober 12

  15. Hype As The Engine Of Acronym Silliness Dienstag, 16. Oktober

    12
  16. Hypermedia Dienstag, 16. Oktober 12

  17. GET /books.json GET /books/1.json Dienstag, 16. Oktober 12

  18. [...] "_links": { ! "self": {"href":"/books/1.json"}, ! "comments":{"href":"/books/1/comments.json"} } [...]

    Dienstag, 16. Oktober 12
  19. Hypermedia As The Engine Of Application State Dienstag, 16. Oktober

    12
  20. REST Dienstag, 16. Oktober 12

  21. Benefits of Hypermedia Dienstag, 16. Oktober 12

  22. API Versioning Dienstag, 16. Oktober 12

  23. foo.com/api/v1/ Dienstag, 16. Oktober 12

  24. Don't do it! Dienstag, 16. Oktober 12

  25. Try to avoid it Dienstag, 16. Oktober 12

  26. Code Duplication Dienstag, 16. Oktober 12

  27. Legacy Code Dienstag, 16. Oktober 12

  28. if request.version < 2 fffffffffuuuuuuuuu! end Dienstag, 16. Oktober 12

  29. if request.version < 2 fffffffffuuuuuuuuu! end Dienstag, 16. Oktober 12

  30. Reasons for versioning Dienstag, 16. Oktober 12

  31. Data structure changes Dienstag, 16. Oktober 12

  32. additions: good subtractions: bad Dienstag, 16. Oktober 12

  33. Different auth mechanism Dienstag, 16. Oktober 12

  34. Support both... Dienstag, 16. Oktober 12

  35. URL changes Dienstag, 16. Oktober 12

  36. A-Ha! Dienstag, 16. Oktober 12

  37. Expose one endpoint Dienstag, 16. Oktober 12

  38. Use Hypermedia to reference other urls Dienstag, 16. Oktober 12

  39. Real World Dienstag, 16. Oktober 12

  40. API iPhone App Android App Mobile Web Desktop App Mashups

    Dienstag, 16. Oktober 12
  41. Shitty connections, expensive data plans, low memory Dienstag, 16. Oktober

    12
  42. Aggregations Dienstag, 16. Oktober 12

  43. Optimisations for different clients Dienstag, 16. Oktober 12

  44. Suggestion Dienstag, 16. Oktober 12

  45. Have a "REST" api Dienstag, 16. Oktober 12

  46. http://stateless.co/hal_specification.html Dienstag, 16. Oktober 12

  47. Build APIs on top of APIs Dienstag, 16. Oktober 12

  48. Authentication Dienstag, 16. Oktober 12

  49. Internal/ External? Dienstag, 16. Oktober 12

  50. Javascript-App? Dienstag, 16. Oktober 12

  51. Session-Based Dienstag, 16. Oktober 12

  52. External? Dienstag, 16. Oktober 12

  53. User based? Dienstag, 16. Oktober 12

  54. SSL+Basic Auth Dienstag, 16. Oktober 12

  55. OAuth2 Dienstag, 16. Oktober 12

  56. Dienstag, 16. Oktober 12

  57. SSL! Dienstag, 16. Oktober 12

  58. http://github.com/songkick/oauth2-provider Dienstag, 16. Oktober 12

  59. Auth inception Dienstag, 16. Oktober 12

  60. App based? Dienstag, 16. Oktober 12

  61. API_KEY API_SECRET Dienstag, 16. Oktober 12

  62. Using authlogic? Dienstag, 16. Oktober 12

  63. http://github.com/phurni/authlogic_api Dienstag, 16. Oktober 12

  64. Building Dienstag, 16. Oktober 12

  65. https://github.com/halfbyte/bookrack/ Dienstag, 16. Oktober 12

  66. ✓ Build an API Dienstag, 16. Oktober 12

  67. POST /books.json GET /books.json GET /books/1.json PUT /books/1.json DELETE /books/1.json

    Dienstag, 16. Oktober 12
  68. $ rails g scaffold Book ... Dienstag, 16. Oktober 12

  69. def index @books = Book.all respond_to do |format| format.html #

    index.html.erb format.json { render json: @books } end end Dienstag, 16. Oktober 12
  70. respond_to :html, :json def index @books = Book.all respond_with @books

    end Dienstag, 16. Oktober 12
  71. [ { "author": "Jan Krutisch", "created_at": "2012-10-14T16:29:17Z", "description": "A funny

    story", "id": 1, "isbn": "", "title": "The Website is Down", "updated_at": "2012-10-14T16:29:17Z" } ] Dienstag, 16. Oktober 12
  72. Customize output Dienstag, 16. Oktober 12

  73. def index @books = Book.all respond_with @books.map{|b| { id: b.id,

    title: b.title, author: b.author, created_at: b.created_at }} end Dienstag, 16. Oktober 12
  74. Dienstag, 16. Oktober 12

  75. jBuilder Dienstag, 16. Oktober 12

  76. Dienstag, 16. Oktober 12

  77. Dienstag, 16. Oktober 12

  78. gem "jbuilder" Dienstag, 16. Oktober 12

  79. books.json.jbuilder Dienstag, 16. Oktober 12

  80. # index.json.jbuilder json.(@books) do |json, book| json.partial! book end Dienstag,

    16. Oktober 12
  81. _book.json.jbuilder Dienstag, 16. Oktober 12

  82. # _book.json.jbuilder json.(book, :id, :title, :author) Dienstag, 16. Oktober 12

  83. Associations Dienstag, 16. Oktober 12

  84. # _book.json.jbuilder json.(book, :id, :title, :author) json.comments(book.comments) do |json, comment|

    json.partial! comment end Dienstag, 16. Oktober 12
  85. # comments/_comment.json.jbuilder json.(comment, :text, :name) Dienstag, 16. Oktober 12

  86. [ { "book": { "id": 1, "title": "The Website is

    down", "author": "Jan Krutisch", "comments": [ { "text": "A shitty comment", "name": "Jan" }, { "text": "Another shitty comment", "name": "Felix Baumgartner" }, { "text": "I disagree!", "name": "Troll" } ] } } ] Dienstag, 16. Oktober 12
  87. + Kind of the right place + Full view infrastructure

    available + Easy to use Dienstag, 16. Oktober 12
  88. I hated .builder Dienstag, 16. Oktober 12

  89. Data structures vs. Content representation Dienstag, 16. Oktober 12

  90. ActiveModel serializers Dienstag, 16. Oktober 12

  91. gem "active_model_serializers" Dienstag, 16. Oktober 12

  92. gem "active_model_serializers" Dienstag, 16. Oktober 12

  93. gem "active_model_serializers", :git => "git://github.com/josevalim/active_model_serializers.git" Dienstag, 16. Oktober 12

  94. serializers/ book_serializer.rb Dienstag, 16. Oktober 12

  95. class BookSerializer < ActiveModel::Serializer attributes :id, :author, :title end Dienstag,

    16. Oktober 12
  96. { "books": [ { "id": 1, "author": "Jan Krutisch", "title":

    "The Website is Down" } ] } Dienstag, 16. Oktober 12
  97. ActiveModel::ArraySerializer.root = false Dienstag, 16. Oktober 12

  98. [ { "id": 1, "author": "Jan Krutisch", "title": "The Website

    is Down" } ] Dienstag, 16. Oktober 12
  99. Associations Dienstag, 16. Oktober 12

  100. class BookSerializer < ActiveModel::Serializer attributes :id, :author, :title has_many :comments

    end Dienstag, 16. Oktober 12
  101. (CommentSerializer) Dienstag, 16. Oktober 12

  102. + mostly declarative, with fallbacks + no view code to

    mangle data structures - no helpers except URL helpers Dienstag, 16. Oktober 12
  103. RABL Dienstag, 16. Oktober 12

  104. gem "rabl" Dienstag, 16. Oktober 12

  105. # books/index.json.rabl collection @books attributes :id, :title, :author Dienstag, 16.

    Oktober 12
  106. Associations Dienstag, 16. Oktober 12

  107. # books/index.json.rabl collection @books attributes :id, :title, :author child :comments

    do attributes :text, :name end Dienstag, 16. Oktober 12
  108. embed? glue? wat? Dienstag, 16. Oktober 12

  109. + Mosty declarative + Full view infrastructure - Kinda ugly,

    kinda weird - (It get's weirder the more you look) Dienstag, 16. Oktober 12
  110. ROAR Dienstag, 16. Oktober 12

  111. Almost like serializers Dienstag, 16. Oktober 12

  112. Both Serializing and Deserializing Dienstag, 16. Oktober 12

  113. HAL implementation Dienstag, 16. Oktober 12

  114. No examples Dienstag, 16. Oktober 12

  115. Testing Dienstag, 16. Oktober 12

  116. Assumption Dienstag, 16. Oktober 12

  117. Test::Unit Dienstag, 16. Oktober 12

  118. 1. Unit testing Dienstag, 16. Oktober 12

  119. It's understood Dienstag, 16. Oktober 12

  120. 2. Integration testing Dienstag, 16. Oktober 12

  121. Rails Dienstag, 16. Oktober 12

  122. require 'test_helper' require 'json' class BooksTest < ActionDispatch::IntegrationTest test "books.json

    should return valid json" do get "/books.json" body = JSON.parse(response.body) assert_not_nil body assert_equal 200, status end end Dienstag, 16. Oktober 12
  123. Rack::Test Dienstag, 16. Oktober 12

  124. require 'test_helper' require 'json' class BooksRackTest < ActiveSupport::TestCase include Rack::Test::Methods

    def app; Rails.application; end test "should return valid json" do get '/books.json' assert last_response.ok? body = JSON.parse(last_response.body) assert_not_nil body end end Dienstag, 16. Oktober 12
  125. require 'test_helper' require 'json' class BooksRackTest < ActiveSupport::TestCase include Rack::Test::Methods

    def app; Rails.application; end test "should return valid json" do get '/books.json' assert last_response.ok? body = JSON.parse(last_response.body) assert_not_nil body end end Dienstag, 16. Oktober 12
  126. Why? Dienstag, 16. Oktober 12

  127. Capybara? Dienstag, 16. Oktober 12

  128. Cucumber? Dienstag, 16. Oktober 12

  129. What to test? Dienstag, 16. Oktober 12

  130. Response Codes Dienstag, 16. Oktober 12

  131. Valid JSON Dienstag, 16. Oktober 12

  132. JSON structure Dienstag, 16. Oktober 12

  133. (keep it simple) Dienstag, 16. Oktober 12

  134. ETags, Cache Headers Dienstag, 16. Oktober 12

  135. Workflows Dienstag, 16. Oktober 12

  136. Interactions Dienstag, 16. Oktober 12

  137. 3. External testing Dienstag, 16. Oktober 12

  138. External Client Dienstag, 16. Oktober 12

  139. (Client Lib?) Dienstag, 16. Oktober 12

  140. Test script Dienstag, 16. Oktober 12

  141. namespace :api_tests do desc "Testing the /books endpoint" task :books

    do require 'rest_client' require 'json' json = JSON.parse( RestClient.get('http://localhost:3000/books.json') ) exit(1) if (json.nil?) end end Dienstag, 16. Oktober 12
  142. Testing >>> Monitoring Dienstag, 16. Oktober 12

  143. Q & A Dienstag, 16. Oktober 12

  144. Thanks! • http://jan.krutisch.de/ • http://twitter.com/halfbyte • https://alpha.app.net/halfbyte • https://github.com/halfbyte •

    http://thesinglepageapp.com Dienstag, 16. Oktober 12
  145. Thanks! • http://jan.krutisch.de/ • http://twitter.com/halfbyte • https://alpha.app.net/halfbyte • https://github.com/halfbyte •

    http://thesinglepageapp.com (shameless plug) Dienstag, 16. Oktober 12