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

よりよいAPIを作るために

 よりよいAPIを作るために

FiNC で開催された Microservices Meetup vol.2 での発表資料です。
http://microservices-meetup.connpass.com/event/36394/

Microservicesで重要になるAPIをどう設計すると美しいかについて話しています。
また、これを実装に落とし込んだサーバージェネレータの https://github.com/wantedly/apig について紹介しています。

Naoyoshi Aikawa

August 09, 2016
Tweet

More Decks by Naoyoshi Aikawa

Other Decks in Technology

Transcript

  1. Wantedlyʹ͍ͭͯ 1 2 3      

        ྫ: ؾͷ߹͏஥ؒͱ΍Γ͍ͨγΰτΛ୳ͤΔαʔϏε ϛογϣϯ:ʮγΰτͰίίϩΦυϧਓΛ૿΍͢ʯ
  2. ✤ Docker͸1೥൒લ͔Βಋೖ ✴ ཧ༝: Heroku͔ΒͷҠߦ ✴ σϓϩΠ࣌ؒΛ୹͔ͨͬͨ͘͠ ✤ OS΋ܦݧ͔ΒશͯCoreOS ✤

    ͱ͸͍͑ɺMonolithic Railsͩͬͨ ✴ ͦΜͳαʔϏεͳ͔ͬͨ͠… ✴ ࠓ͸αʔϏε΋૿͑ɺ࣮ࡍʹϚΠΫϩαʔϏε Խ͖͍ͯͯ͠Δ Wantedlyͷݱঢ়
  3. 1. ͜ͷ࣌఺ΑΓɺશͯͷνʔϜ͸αʔϏεΠϯλʔϑΣʔεΛ௨ͯ͡શͯ ͷσʔλͱػೳΛެ։͢Δ͜ͱ 2. ֤νʔϜ͸֤ʑͦͷΠϯλʔϑΣʔεΛ௨ͯ͡௨৴͠ͳ͚Ε͹ͳΒͳ͍ 3. ͦͷଞͷશͯͷϓϩηεؒ௨৴͸ڐՄ͞Εͳ͍ɻμΠϨΫτϦϯΫɺ ଞͷνʔϜͷσʔλιʔε͔Β௚઀σʔλΛಡΉ͜ͱɺϝϞϦڞ༗Ϟ σϧɺόοΫυΞɺશͯΛې͡ΔɻωοτϫʔΫӽ͠ͷαʔϏεΠϯλʔ ϑΣʔεΛܦ༝ͨ͠௨৴͚͕ͩڐՄ͞ΕΔ

    4. ࢖༻͢Δٕज़͸໰Θͳ͍ɻ HTTP ɺ Corba ɺ Pubsub ɺ ΧελϜϓ ϩτίϧɺԿͰ΋ྑ͍ɻ Bezos ͸ؾʹ͠ͳ͍ 5. શͯͷαʔϏεΠϯλʔϑΣʔε͸ɺྫ֎ͳ͘ɺ֎෦ʹެ։ՄೳͳΑ͏ ʹθϩ͔Βઃܭ͞Εͳ͚Ε͹ͳΒͳ͍ɻ͢ͳΘͪɺνʔϜ͸શੈքͷ σϕϩούʹ޲͚ͯΠϯλʔϑΣʔεΛެ։͢Δ͜ͱ͕Ͱ͖ΔΑ͏ɺઃ ܭ͠ɺܭը͠ͳ͚Ε͹ͳΒͳ͍ɻྫ֎͸ແ͍ 6. ͦ͏͠ͳ͍ऀ͸ղޏ͞ΕΔ 2002೥ʹAmazonͷࣾ௕͕ग़ͨ࢘͠ྩ http://anond.hatelabo.jp/20111018190933
  4. 1. ͜ͷ࣌఺ΑΓɺશͯͷνʔϜ͸αʔϏεΠϯλʔϑΣʔεΛ௨ͯ͡શͯ ͷσʔλͱػೳΛެ։͢Δ͜ͱ 2. ֤νʔϜ͸֤ʑͦͷΠϯλʔϑΣʔεΛ௨ͯ͡௨৴͠ͳ͚Ε͹ͳΒͳ͍ 3. ͦͷଞͷશͯͷϓϩηεؒ௨৴͸ڐՄ͞Εͳ͍ɻμΠϨΫτϦϯΫɺ ଞͷνʔϜͷσʔλιʔε͔Β௚઀σʔλΛಡΉ͜ͱɺϝϞϦڞ༗Ϟ σϧɺόοΫυΞɺશͯΛې͡ΔɻωοτϫʔΫӽ͠ͷαʔϏεΠϯλʔ ϑΣʔεΛܦ༝ͨ͠௨৴͚͕ͩڐՄ͞ΕΔ

    4. ࢖༻͢Δٕज़͸໰Θͳ͍ɻ HTTP ɺ Corba ɺ Pubsub ɺ ΧελϜϓ ϩτίϧɺԿͰ΋ྑ͍ɻ Bezos ͸ؾʹ͠ͳ͍ 5. શͯͷαʔϏεΠϯλʔϑΣʔε͸ɺྫ֎ͳ͘ɺ֎෦ʹެ։ՄೳͳΑ͏ ʹθϩ͔Βઃܭ͞Εͳ͚Ε͹ͳΒͳ͍ɻ͢ͳΘͪɺνʔϜ͸શੈքͷ σϕϩούʹ޲͚ͯΠϯλʔϑΣʔεΛެ։͢Δ͜ͱ͕Ͱ͖ΔΑ͏ɺઃ ܭ͠ɺܭը͠ͳ͚Ε͹ͳΒͳ͍ɻྫ֎͸ແ͍ 6. ͦ͏͠ͳ͍ऀ͸ղޏ͞ΕΔ 2002೥ʹAmazonͷࣾ௕͕ग़ͨ࢘͠ྩ http://anond.hatelabo.jp/20111018190933 = APIͰશͯΛߦ͑
  5. Microservices׬੒ܗ API Gateway Swift Android Java React Angular API Request

    API Request Kong Kubernetes Go Rails Python api.wantedly.com /bot /v2 /v1 Mobile PC
  6. Microservices׬੒ܗ API Gateway Swift Android Java React Angular API Request

    API Request Kong Kubernetes Go Rails Python api.wantedly.com /bot /v2 /v1 Mobile PC
  7. Ұ؏ͨ͠ύε໊Λ࢖͏ Ϧιʔε • ඪ४Ͱෳ਺ܗʹ͢Δ • γεςϜશମͰγϯάϧτϯͳ৔߹͸ɺ୯਺ܗ ΞΫγϣϯ • جຊHTTPϝιουͳͷͰಈࢺ͸ؚΊͳ͍ •

    ඞཁͳ৔߹͸ɺΞΫγϣϯ໊Λactionsͷޙʹଓ͚ͯهड़ Φϓγϣϯ • ໊ࢺͰ͸ͳ͍ͷͰɺύεͰ͸ͳ͘ΫΤϦύϥϝʔλͰઃఆ͢Δ /resources/:id/actions/:action
  8. ϑΟʔϧυΛߜΔΫΤϦΛ͚ͭΔ APIʹେ੾ͳ͜ͱ • ͍͔ʹޮ཰తʹૣ͘σʔλऔಘͰ͖Δ͔ • ίʔϧ਺ΛۃྗݮΒ͢ • 1ίʔϧ͋ͨΓͷσʔλ௨৴ྔΛۃྗݮΒ͢ ? fieldsΫΤϦ

    • Ϩεϙϯεʹ͓͍ͯࢦఆͨ͠field໊ͷΈΛநग़ͨ͠ܗͰฦ͢Α͏ʹϨεϙϯ εΛϑΟϧλϦϯά͢Δ • ΍Γ͗͢Ͱ͕͢ɺFacebook͸fieldsΛࢦఆ͠ͳ͍ͱϨεϙϯε͸ۭʹͳΔ [ { "id": 10, "name": "shirt", "age": 30, "email": "hoge@hoge.com", "tel": "090XXXXXXXX", }, { "id": 11, …… [ { "id": 10, "name": "shirt", }, { "id": 11, "name": "hoge", }, …… ]
  9. Version͸HeaderͰ؅ཧ͢Δ 63-ͩͱ FYBNQMFDPNWVTFST w Ϧιʔεʹόʔδϣϯؚ͕·Εͯඒ͘͠ͳ͍ w 3PVUJOHͷॲཧ΍63-͔ΒόʔδϣϯΛऔಘ͢Δͷ΋Ұखؒ )FBEFSͩͱ "DDFQUTBQQMJDBUJPOKTPOWFSTJPO w

    3&45ͷݪଇʹै͍ͬͯΔΑΓඒ͍͠63*ߏ੒ w $POUSPMMFS಺Ͱͷ෼ذ΋ΫϥΠΞϯτଆͷऔಘ΋ॻ͖΍͍͢ Server΋Client΋ѻ͍ͮΒ͍ Server΋Client΋ѻ͍΍͍͢
  10. Version෼ذ͸ݶہ෼ذ • Controller෼ׂ͸อक͕ඇৗʹࠔ೉ • ґଘύοέʔδͷΞοϓσʔτͰੲͷ࣮૷Λ͍͡Δ ࿑ྗ͸ඞͣੜ͡Δ • Controller಺ͷݶఆతͳ෼ذͰ؅ཧ͢Δ • ܗࣜ͸SemanticVersioningΛ࢖͏

    if version.Range(ver, "<", "1.0.0") { // conditional branch by version. // this version < 1.0.0 !! c.JSON(400, gin.H{"error": "this version (< 1.0.0) is not supported!"}) return }
  11. meta-data͕Bodyʹ͋Δͱѻ͍ͮΒ͍ • ड͚औΓ͔ͨͬͨσʔλ͕௚ײతʹΘ͔Βͳ͍ • ΫϥΠΞϯτଆ͸ύʔε͢ΔҰख͕ؒੜ͡Δ • αʔόʔଆʹͱͬͯ΋Ճ޻ͮ͠Β͍ • ྫ͑͹ɺෳ਺ͷAPIΛ̍ͭʹՃ޻ͯ͠ฦ͢ࡍʹҰͭҰͭύʔεͯ͠ meta-dataΛऔΓআ͔ͳ͍ͱ͍͚ͳ͍

    { "data": [ ... Endpoint data is here ], "paging": { "previous": "/albums?limit=25&amp;after=MTAxNTExOTQ1MjAwNzI5NDE=", "next": "/albums?limit=25&amp;after=MTAxNTExOTQ1MjAwNzI5NDE=" } } BodyʹೖΕΔͱ…(Facebook) Server΋Client΋ѻ͍ͮΒ͍
  12. Paging΋HeaderͰఏڙ͢Δ • BodyͷϨεϙϯε͕௚ײతʹ • Ճ޻͠΍͍͢Ϩεϙϯε HTTP/1.1 200 OK Content-Type: application/json;

    charset=utf-8 Link: <https://api.github.com/search/code?q=addClass+user%3Amozilla&page=15>; rel="next", <https://api.github.com/search/code?q=addClass+user%3Amozilla&page=34>; rel="last", <https://api.github.com/search/code?q=addClass+user%3Amozilla&page=1>; rel="first", <https://api.github.com/search/code?q=addClass+user%3Amozilla&page=13>; rel="prev" Date: Mon, 01 Aug 2016 03:33:50 GMT Content-Length: 5 [ { "id": 10, "name": "shirt" }, { "id": 11, "name": "shirt" } ] HeaderʹLinkͱͯ͠ೖΕΔ(Github) Server΋Client΋ѻ͍΍͍͢
  13. ద੾ͳPagingΛ೺Ѳ͓ͯ͘͠ Listܕ • ࣌ܥྻʹ͍ͭͯ͸ͩ͜ΘΒͣɺฦ͞ΕͨಛఆͷΦϒδΣΫτͷϦετ • sample.com/users?page=2&limit=5 Feedܕ • σʔλͷϦετͰಛఆͷ࣌ؒ, idΛ࢖ͬͯɺιʔτͨ͠ϨεϙϯεΛฦ

    ͢ • sample.com/users?limit=5&last_id=100&order=desc Cursorܕ • Ϩεϙϯε಺ͷಛఆͷΞΠςϜʹϚʔΫΛ෇͚ͨτʔΫϯΛج఺ʹͯ͠ લޙΛಡΈࠐΉ • SNSͳͲͷେྔͷ௥Ճ࡟আ͕ൃੜ͢Δ΋ͷΛਖ਼֬ʹऔಘ͢Δ