Upgrade to Pro — share decks privately, control downloads, hide ads and more …

API Blueprint速習会 @Wantedly

API Blueprint速習会 @Wantedly

Wantedly( https://www.wantedly.com/ )が行っている社内速習会

Go Takagi

May 12, 2016
Tweet

More Decks by Go Takagi

Other Decks in Programming

Transcript

  1. ໘౗ͳཁҼ • ࢓༷ॻͷϑΥʔϚοτ͕ఆ·͍ͬͯͳ͍ɻ • JSON Schemaʁ Swaggerʁ • ࣅͨΑ͏ͳ͜ͱΛ܁Γฦ͠ॻ͘͜ͱ΋ଟ͍ •

    ։ൃ༻ͷϞοΫ΋͍Δ • υΩϡϝϯτͱݱঢ়ͱͷ੔߹ੑ(maintenance) • υΩϡϝϯτ͸͋Δ͕ɺ·࣮ͩࡍʹಈ͘΋ͷ͕࣮૷͞Ε͍ͯͳ͍ 
  2. API Blueprint • MarkdownͰهड़͞ΕͨWeb API(ಛʹRESTful ͳAPI)ͷ࢓༷Λղऍͯ͘͠ΕΔ • ਓ͕ಡΈ΍͍͢ʂ • ԿΛ࡞ΕΔ͔

    • υΩϡϝϯτ(aglio) • ϞοΫαʔόʔ(api-mock) • ςετ࣮ߦ(dredd) • ·ͱΊͯੜ੒Ͱ͖Δ͔ΒapibϑΝΠϧΛ؅ཧ͢Δ͚ͩͰࡁΉ 
  3. ࠓ೔ͷ͓͠ͳ͕͖ • apiblueprintΛମݧʂ • Hello world! • γϯϓϧͳRestAPIΛհͯ࣍͠ͷ3ͭΛ΍ͬͯΈΔ • υΩϡϝϯτ

    • ϞοΫαʔόʔ • ؆୯ͳςετ • rails gͰapibϑΝΠϧΛੜ੒͢ΔGemͷ঺հ 
  4. Install Battle λʔϛφϧͰҎԼΛೖྗ $ gem install rails dredd_hooks $ brew

    install node npm $ npm install -g aglio api-mock dredd • API Blueprint͸࢓༷ॻͳͷͰॲཧܥ͸ผ • ࠓճ͸Node.jsΛ࢖࣮ͬͯ૷͞Εͨaglioͱapi-mockͱdreddΛར༻ • aglio υΩϡϝϯτੜ੒ • api-mock ϞοΫαʔόʔੜ੒ • dredd ςετ࣮ߦ 
  5. Editor Package • Sublimetext • API Blueprint
 https://github.com/apiaryio/api-blueprint-sublime-plugin • Atom

    • language-api-blueprint
 https://github.com/danielgtaylor/atom-language-api-blueprint • Vim • apiblueprint.vim
 https://github.com/kylef/apiblueprint.vim 
  6. Hello world! • ͜Ε͸/messageʹGETϝιουΛ࣮ߦ͢Δͱ Content-Type͕text/plainͷ"Hello, World!"͕ฦΔ $ cat << 'EOF'

    > helloworld.apib # GET /message + Response 200 (text/plain; charset=utf-8) Hello, World! EOF 
  7. υΩϡϝϯτੜ੒ • 2௨Γͷख๏ • HTMLʹม׵ $ aglio -i helloworld.apib -o

    helloworld.html  • Preview serverΛཱͯΔ • apibϑΝΠϧΛsave͢Δͨͼʹੜ੒͠ͳ͓ͯ͘͠ΕΔ • save࣌ʹจ๏Τϥʔ΋νΣοΫͯ͘͠ΕΔ $ aglio -i helloworld.apib -s
  8. Restful API GET /message  • HTTPϝιου͸ϦιʔεΛͲ͏ૢ࡞͍͔ͨ͠Λද͢ • ϦιʔεɿWeb্ʹଘࡏ͢Δʮ৘ใʯ •

    URL͸Ϧιʔεͷ໊લ • APIͷॲཧͷ݁Ռ͸ɺεςʔλεɾίʔυͰද͢ • ͜ͷ৔߹͸/messageʹGETͱ͍͏ૢ࡞Λ͍ͨ͠
  9. user API • ࠓճ͸Ruby on RailsΛ༻͍ͯɺγϯϓϧͳRestfulAPIΛ࡞੒͢Δ • ·ͣ͸RailsͰҎԼΛ࣮ߦ $ rails

    new apib-sample --api -T $ cd apib-sample $ rails g scaffold User name age:integer admin:boolean $ rake db:migrate  • --api͸APIϞʔυ (apiʹؔ͠ͳ͍ϑΝΠϧΛੜ੒͠ͳ͍) • -T͸--skip-test-unit (TestUnitΛ૊Έࠐ·ͳ͍) • rails g scaffold • σʔλϕʔε΁ͷςʔϒϧ΁ͷొ࿥(CREATE)ɺࢀর(READ)ɺߋ৽(UPDATE)ɺ࡟আ ʢDELETEʣͱ͍͏CRUDΛߦ͏WebΞϓϦέʔγϣϯͷͻͳܕͱͳΔίʔυΛࣗಈੜ੒ɻ
  10. user API  VTFS"1*ͷॲཧ಺༰ ର৅ͱͳΔϦιʔε ࣮ߦΞΫγϣϯ VTFSΛ௥Ճ͢Δ VTFSશମ 1045VTFST VTFSΛશͯऔಘ͢Δ

    VTFSશମ (&5VTFST *EͱҰக͢ΔVTFSΛऔಘ͢Δ *EͱҰக͢ΔVTFS (&5VTFST\JE^ *EͱҰக͢ΔVTFSΛߋ৽͢Δ *EͱҰக͢ΔVTFS 165VTFST\JE^ *EͱҰக͢ΔVTFSΛ࡟আ͢Δ *EͱҰக͢ΔVTFS %&-&5&VTFST\JE^
  11. user API  VTFS"1*ͷॲཧ಺༰ ॲཧͷ݁ՌฦΔ)551Ϩεϙϯε εςʔλείʔυ #PEZ VTFSΛ௥Ճ͢Δ  ௥Ճͨ͠σʔλ

    VTFSΛશͯऔಘ͢Δ  ର৅σʔλ *EͱҰக͢ΔVTFSΛऔಘ͢Δ  ର৅σʔλ *EͱҰக͢ΔVTFSΛߋ৽͢Δ  ߋ৽ͨ͠σʔλ *EͱҰக͢ΔVTFSΛ࡟আ͢Δ  ۭ
  12. user API • ద౰ʹuserΛ௥Ճ͢Δ $ rails console irb(main):001:0> User.create(name: "Go

    Takagi", age: 22, admin: true) irb(main):002:0> User.create(name: "Dean Fujioka", age: 35, admin: false) irb(main):003:0> User.create(name: "Kasumi Arimura", age: 23, admin: false) 
  13. user API • RailsΛ্ཱͪ͛ͯΞΫηεͯ͠ΈΔ $ rails server => Booting Puma

    => Rails 5.0.0.rc1 application starting in development on http://localhost:3000 => Run `rails server -h` for more startup options  • jsonϑΝΠϧ͕ฦ͖ͬͯͨʂ
  14. user.apib  FORMAT: 1A HOST: http://localhost:3000 # user API Welcome

    to the user API. # users action [/users] ## Create user [POST] ## Get users [GET] # user action [/users/{id}] ## Get user [GET] ## Update user [PUT] ## Delete user [DELETE] # Data Structures ## users (object)
  15. Metadata section • API Blueprint͸υΩϡϝϯτͷઌ಄σʔλ͕ϝλσʔλ ηΫγϣϯͱͳ͍ͬͯΔ • কདྷతͳ֦ுͳͲʹඋ͑ͯόʔδϣϯ৘ใΛهࡌͰ͖Δ • ݱࡏ͸1A

    • ఏڙ͢Δαʔόʔͷϗετ΋هड़Մೳ  FORMAT: 1A HOST: http://localhost:3000 # user API Welcome to the user API. # users action [/users] ## Create user [POST] ## Get users [GET] # user action [/users/{id}] ## Get user [GET] ## Update user [PUT] ## Delete user [DELETE] # Data Structures ## users (object)
  16. API name & overview section • # user API ͕APIͷ໊শ

    • ԼʹAPIશମͷઆ໌͕ॻ͚Δ  FORMAT: 1A HOST: http://localhost:3000 # user API Welcome to the user API. # users action [/users] ## Create user [POST] ## Get users [GET] # user action [/users/{id}] ## Get user [GET] ## Update user [PUT] ## Delete user [DELETE] # Data Structures ## users (object)
  17. Resource sections • ઃܭॻͷϝΠϯ • ۩ମతͳશମ૾͸ӈͷΑ͏ʹͳΔ • Ϧιʔε͝ͱʹݟग़͠ͰάϧʔϓΛ͘͘Γɺ HTTPϝιουΛҰͭԼͷϨϕϧͰॻ͘ 

    FORMAT: 1A HOST: http://localhost:3000 # user API Welcome to the user API. # users action [/users] ## Create user [POST] ## Get users [GET] # user action [/users/{id}] ## Get user [GET] ## Update user [PUT] ## Delete user [DELETE] # Data Structures ## users (object)
  18. (࠶ܝ)user API  VTFS"1*ͷॲཧ಺༰ ର৅ͱͳΔϦιʔε ࣮ߦΞΫγϣϯ VTFSΛ௥Ճ͢Δ VTFSશମ 1045VTFST VTFSΛશͯऔಘ͢Δ

    VTFSશମ (&5VTFST *EͱҰக͢ΔVTFSΛऔಘ͢Δ *EͱҰக͢ΔVTFS (&5VTFST\JE^ *EͱҰக͢ΔVTFSΛߋ৽͢Δ *EͱҰக͢ΔVTFS 165VTFST\JE^ *EͱҰக͢ΔVTFSΛ࡟আ͢Δ *EͱҰக͢ΔVTFS %&-&5&VTFST\JE^
  19. (࠶ܝ)user API  VTFS"1*ͷॲཧ಺༰ ॲཧͷ݁ՌฦΔ)551Ϩεϙϯε εςʔλείʔυ #PEZ VTFSΛ௥Ճ͢Δ  ௥Ճͨ͠σʔλ

    VTFSΛશͯऔಘ͢Δ  ର৅σʔλ *EͱҰக͢ΔVTFSΛऔಘ͢Δ  ର৅σʔλ *EͱҰக͢ΔVTFSΛߋ৽͢Δ  ߋ৽ͨ͠σʔλ *EͱҰக͢ΔVTFSΛ࡟আ͢Δ  ۭ
  20. Get users [GET /users]  ## Get users [GET] Returns

    user list. + Response 200 (application/json; charset=utf-8) + Attributes (array) + Attributes (object) + id: 1 (number) - Id + name: NAME (string) + age: 1 (number) + admin: false (boolean) + created_at: `2000-01-01 00:00:00` (string) - CreatedTime + updated_at: `2000-01-01 00:00:00` (string) - UpdatedTime • #ͷ௚ޙʹ໊শɺԼʹઆ໌Λॻ͚Δ • action͸”+”Λ༻͍ͯListͰॻ͍͍ͯ͘ • ࠓճ͸഑ྻΛฦ͢Response 200
  21. Header • ੜ੒͞ΕͨυΩϡϝϯτͰ͸Headerʹapplication/json; charset=utf-8͕ࢦఆ͞Ε͍ͯΔ • ΑΓઃఆ͕ඞཁͳΒ+Attributesͱಉ͡֊૚ʹ+HeadersͰهࡌ  + Response 200

    (application/json; charset=utf-8) + Headers Connection: keep-alive Content-Type: multipart/form-data, boundary=AaB03x + Attributes (array) + Attributes (object)
  22. Create user [POST /users]  ## Create user [POST] Create

    a new user + Request users (application/json; charset=utf-8) + Attributes + name: NAME (string) + age: 1 (number) + admin: false (boolean) + Response 201 (application/json; charset=utf-8) + Attributes + id: 1 (number) - Id + name: NAME (string) + age: 1 (number) + admin: false (boolean) + created_at: `2000-01-01 00:00:00` (string) - CreatedTime + updated_at: `2000-01-01 00:00:00` (string) - UpdatedTime
  23. Data Structures • ಉ͡σʔλΛԿ౓΋࢖͏ͷ͸໘౗ͩ͠ͳΜ͔಄ѱ͍ • Data Structuresʹఆ͓͚ٛͯ͠͹ݺͼग़͢͜ͱ͕Մೳ  # Data

    Structures ## users (object) + id: 1 (number) - Id + name: NAME (string) + age: 1 (number) + admin: false (boolean) + created_at: `2000-01-01 00:00:00` (string) - CreatedTime + updated_at: `2000-01-01 00:00:00` (string) - UpdatedTime FORMAT: 1A HOST: http://localhost:3000 # user API Welcome to the user API. # users action [/users] ## Create user [POST] ## Get users [GET] # user action [/users/{id}] ## Get user [GET] ## Update user [PUT] ## Delete user [DELETE] # Data Structures ## users (object)
  24. Data Structures • ͢Δͱ͜ͷΑ͏ʹݺ΂Δɻ͖ͬ͢Γ  ## Create user [POST] Create

    a new user + Request users (application/json; charset=utf-8) + ……… + Response 201 (application/json; charset=utf-8) + Attributes (users) ## Get users [GET] Returns user list. + Response 200 (application/json; charset=utf-8) + Attributes (array) + (users)
  25. Parameter /users{id}  # user action [/users/{id}] + Parameters +

    id: `1` (enum[string]) - The ID of the desired user. + Members + `1` + `2` + `3` ## Get user [GET] • parameter͕͋Δ৔߹͸ॳΊʹ+parameterΛఆٛ͢Δͱ Ҏ߱ͷϦΫΤετશͯͰར༻ग़དྷΔ • ࠓճ͸MembersΛड͚ೖΕΔ࢓༷ʹ͕ͨ͠ଞʹॳظ஋΍ required΋ઃఆͰ͖Δ
  26. Get user [POST /users{id}]  # user action [/users/{id}] +

    Parameters + id: `1` (enum[string]) - The ID of the desired user. + Members + `1` + `2` + `3` ## Get user [GET] Returns user. + Response 200 (application/json; charset=utf-8) + Attributes (users)
  27. Update user [PUT /users{id}]  ## Update user [PUT] update

    user. + Request users (application/json; charset=utf-8) + Attributes + name: NAME (string) + age: 1 (number) + admin: false (boolean) + Response 200 (application/json; charset=utf-8) + Attributes (users) • ߋ৽σʔλΛRequest • (idͷσʔλΛ্ॻ͖ͯ͠)Response 200
  28. Delete user [DELETE /users{id}]  ## Delete user [DELETE] Delete

    user. + Response 204 • (idͷσʔλΛ࡟আͯ͠) Response 204
  29. POSTσʔλͷҰ࣌อଘ • apibϑΥϧμʹdredd_hooks.rbϑΝΠϧΛ࡞੒ • transaction͔ΒPOSTͷσʔλΛୀආ  require 'json' include DreddHooks::Methods

    response_stash = {} after "users action > Create user" do |transaction| # saving HTTP response to the stash response_stash[transaction['name']] = transaction['real'] end
  30. idͷऔಘ • response_stash͔ΒidΛऔಘ͢Δؔ਺ͷఆٛ  def get_input(transaction, response_stash) #reusing data from

    previous response here parsed_body = JSON.parse response_stash['users action > Create user'] ['body'] machine_id = parsed_body['id'] #replacing id in URL with stashed id from previous response transaction['fullPath'].gsub! '1', machine_id.to_s end
  31. hooksͷઃఆ • parameterΛ༻͍ΔΞΫγϣϯͷલʹઌʹఆٛ ͨؔ͠਺Λݺͼग़͢  before "user action > Get

    user" do |transaction| get_input(transaction, response_stash) end before "user action > Update user" do |transaction| get_input(transaction, response_stash) end before "user action > Delete user" do |transaction| get_input(transaction, response_stash) end
  32.  require 'json' include DreddHooks::Methods response_stash = {} def get_input(transaction,

    response_stash) #reusing data from previous response here parsed_body = JSON.parse response_stash['users action > Create user']['body'] machine_id = parsed_body['id'] #replacing id in URL with stashed id from previous response transaction['fullPath'].gsub! '1', machine_id.to_s end after "users action > Create user" do |transaction| # saving HTTP response to the stash response_stash[transaction['name']] = transaction['real'] end before "user action > Get user" do |transaction| get_input(transaction, response_stash) end before "user action > Update user" do |transaction| get_input(transaction, response_stash) end before "user action > Delete user" do |transaction| get_input(transaction, response_stash) end
  33. configϑΝΠϧͷੜ੒ • λʔϛφϧͰapibϑΥϧμ্Ͱdredd initΛ࣮ߦ͠ɺ ԼઢͷΑ͏ʹઃఆ • ࢒Γ͸Enter  $ dredd

    init ? Location of the API blueprint (apiary.apib) user.apib ? Command to start API backend server e.g. (bundle exec rails server) rails server -b 0.0.0.0 ? URL of tested API endpoint http://localhost:3000 ? Programming language of hooks ruby ? Do you want to use Apiary test inspector? (Y/n)
  34. ࣮ߦ • ੜ੒͞Εͨdredd.ymlͷҎԼͷͱ͜ΖΛEdit  $ dredd complete: 5 passing, 0

    failing, 0 errors, 0 skipped, 5 total complete: Tests took 2173ms complete: See results in Apiary at: https://app.apiary.io/public/ tests/run/f961c845-e6c6-4020-9d06-5c5545841b16 info: Sending SIGTERM to the backend server - Gracefully stopping, waiting for requests to finish === puma shutdown: 2016-05-10 21:04:36 +0900 === - Goodbye! Exiting
  35. apiblueprint-rails • ੜ੒͢Δͱ͖ʹscaffoldίϚϯυ΋Ұॹʹݺͼग़͢ • ΦϓγϣϯͰ੾Γସ͑Մೳ • —apidoc-dirͰੜ੒ϑΥϧμΛมߋ • —generate-typeͰੜ੒ίϚϯυΛมߋ(none, model,

    …)  $ rails g apiblueprint Person name age:integer admin:boolean create doc/person.apib invoke active_record create db/migrate/20160511104619_create_people.rb create app/models/person.rb invoke resource_route route resources :people invoke scaffold_controller create app/controllers/people_controller.rb
  36.  FORMAT: 1A # person API Write an overall API

    discription. # people action [/people] Write a discription. ## Create person [POST] Write a [POST] discription. + Request people (application/json; charset=utf-8) + Attributes + name: MyString (string) + age: 1 (number) + admin: false (boolean) + Response 201 (application/json; charset=utf-8) + Attributes (people) ## Delete person [DELETE] Write a [DELETE] discription. + Response 204 # Data Structures ## people (object) + id: 1 (number) - Id + name: MyString (string) + age: 1 (number) + admin: false (boolean) + created_at: `2000-01-01 00:00:00` (string) - CreatedTime + updated_at: `2000-01-01 00:00:00` (string) - UpdatedTime