Rails and JSON APIIn 2019Akinori Musha (@knu)
View Slide
JSON API In 2019• JSON:API• OpenAPI
JSON:API
JSON:API• RESTfulͳAPIʹ͓͍ͯɺREST͕نఆ͍ͯ͠ͳ͍͕΅ΜΓఆࣜԽ͖ͯͨ͠ϓϥΫςΟεΛن֨ͱͯ͠औΓ·ͱΊ͍ͯΔͷhttps://jsonapi.org/• JSONΛϕʔεͱͨ͠ཁٻɾԠϑΥʔϚοτΛࡦఆ• HALͳͲͷൃలܥɺܾఆ൛• ཤྺ• 201812݄ 1.1RC• 2015 5݄ 1.0࠷ऴ൛• 2013 5݄ ࠷ॳͷυϥϑτ
RESTͱ• 2000ɺApache HTTP ServerϓϩδΣΫτͷcofounderͰHTTP/1.1ͷࡦఆʹؔΘͬͨRoy Fielding͕ത࢜߸จͰఏএ• REpresentational State Transferͷ಄ࣈޠ• REpresentational State = දݱՄೳͳঢ়ଶ = ͍ΘΏΔϦιʔε• Transfer = సૹ• HTTPʹ্ΛՍͨ͠ϝλRPCϓϩτίϧʢSOAPXMLRPCʣɺHTTPΛ୯ͳΔτϥϯεϙʔτɾτϯωϧͱ͖ͯͬͯͨ͠༻๏ʹର͢ΔΞϯνςʔθ• HTTPݪཧओٛ
JSONͱ• 2001ɺDouglas Crockford͕WebϕʔεͷΞϓϦέʔγϣϯΛ։ൃ͢Δࡍʹʮൃݟʯͨ͠σʔλަϑΥʔϚοτ• The JSON Saga▶• ୯ͳΔJavaScriptͷΦϒδΣΫτϦςϥϧͰHTMLυΩϡϝϯτʹຒΊࠐΉࡍʹ·͍ͣͱؾ͍ͮͨ• ΩʔΛඞͣΫΦʔτ͢Δ• ES3Ͱ༧ޠΛΩʔʹͰ͖ͳ͔ͬͨ(ES5ͰՄೳʹͳͬͨ)• Pythonͷdictionaryͷه๏ͱҰக͍ͯͨ͠• eval("{a:42}")ͯ͠ΈΔͱ͔Δ͕ɺϒϩοΫʹϥϕϧa:ͱࣜ42͕͋Δͱղऍ͞Εͯ͠·͏ɺͱ͍͏ཧ༝͋Δ• จࣈྻϦςϥϧʹͳ \ Λڐ͢• Λ ͱ͢ΔͳͲͯ͠ແޮԽͰ͖ΔΑ͏ʹ• evalͰ͖Δͱ͍͏ख͔ܰ͞Β࢝·͕ͬͨɺ҆શΛ֬ೝੑ͢Δͷ͕େม• ઐ༻ύʔαʔ͕ඞཁ(JSON.parse)
RESTͱ• 4ͭͷݪଇ• Addressabilityͯ͢ͷૢ࡞ରURIʢϢχόʔαϧʹϢχʔΫͳ໊લʣͰࣔ͞ΕΔ• Statelessnessηογϣϯͷঢ়ଶཧͤͣɺݸʑͷૢ࡞͕ಠཱ͍ͯ͠Δ• Connectednessใͷؔ࿈URIͷϦϯΫͰࣔ͢• Uniform InterfaceHTTPϝιουΛڞ௨ޠኮͱ͠ɺ͋ΒΏΔૢ࡞ΛGET, POST, PUT, DELETEͰද͢
OpenAPI
OpenAPI Specification• 2017ʹग़ͨɺRESTful APIͷ༷Λهड़͢ΔͨΊͷݴޠʢJSON|YAMLʣ• https://www.openapis.org/• Swagger Specification (ʙ2.0)ͷޙܧ• SwaggerRESTful APIΛߏங͢ΔͨΊͷϑϨʔϜϫʔΫɾπʔϧʢ2011ʙʣ
OpenAPI Specification (3.0)• ཤྺ• 2018-10-08 OpenAPI Specification 3.0.2• 2017-12-06 OpenAPI Specification 3.0.1• 2017-07-26 OpenAPI Specification 3.0.0• 2016-01-01 OpenAPI Initiativeൃ• 2014-09-08 Swagger Specification 2.0• 2014-03-14 Swagger Specification 1.2• 2012-08-22 Swagger Specification 1.1• 2011-08-10 Swagger Specification 1.0
OpenAPI Specification (3.0)• ΤϯυϙΠϯτͱཁٻɾԠͷσʔλεΩʔϚͳͲΛแׅతʹهड़Ͱ͖Δ• JSON:APIɺHALͱߦͨ֓͠೦• JSON SchemaΛऔΓࠐΜͰεΩʔϚఆٛݴޠͱͯ͠ར༻͍ͯ͠Δ• શʹಉظɾਵ͍ͯ͠ΔΘ͚Ͱͳ͍(JSON Schema͖ʹΓυϥϑτΛॏͶ͍ͯͯɺखΓଟ͍)• JSON Hyper Schemaͱগ͔͠Ϳ͍ͬͯΔ• OpenAPI͕ࣗಠࣗʹΤϯυϙΠϯτใͷهड़ݴޠΛ͍࣋ͬͯΔ• OpenAPIΫΤϦʔύϥϝʔλύεύϥϝʔλʹ͍ͭͯbodyಉ༷ʹ౷Ұతͳจ๏Ͱهड़Ͱ͖ΔΑ͏ʹਐԽ
JSON Schema
JSON Schema• JSONσʔλͷεΩʔϚͷهड़ݴޠhttps://json-schema.org/• ͦΕࣗମ͕JSONͰهड़͞ΕΔ• ҎԼͷ༷ͷ૯শ• JSON Schema Core• JSON Schema Validation• JSON Hyper-Schema• Relative JSON Pointers• ཤྺ• 2018-03-19 draft-07
JSON Schema• JSON Schema Core• JSON Schemaͷج൫༷εΩʔϚόʔδϣϯͷએݴɺωετɺ෦ɾ֎෦ࢀরͳͲʹ͍ͭͯنఆ͞Ε͍ͯΔ$schema, $ref, $idͳͲͦͷଞͷ۩ମతͳޠኮ͜͜Ͱنఆ͞Ε͍ͯͳ͍• JSON Schema Validation• JSON Schemaͷ༷ͷຊମσʔλܕɺόϦσʔγϣϯϧʔϧΛهड़͢ΔͨΊͷޠኮ͕ఆٛ͞Ε͍ͯΔɺ࣌ࠁɺϝʔϧΞυϨεɺURIͳͲσʔλܕͱͯ͠ఆٛ͞Ε͍ͯΔ(JSONදݱࣗମString)
JSON Schema• JSON Hyper-Schema• ϋΠύʔϝσΟΞ(ϦϯΫ)Λهड़͢ΔͨΊͷޠኮ͕ఆٛ͞Ε͍ͯΔ• Relative JSON Pointers• JSONυΩϡϝϯτͷಛఆͷΩʔΛࢀর͢ΔͨΊͷه๏$refͰ # Ҏ߱ʹهड़͢ΔΞϯΧʔͰΘΕΔ
RailsͰJSON:API
RailsͰJSON:API• OpenAPI 3.0Ͱهड़ͯ͠Έ͍ͨ• JSON:APIͰͬͯΈ͍ͨ
OpenAPI 3.0Ͱهड़ͯ͠Έ͍ͨ• committee gemΛͬͯΈͨγϯϓϧʹཁٻɾԠόϦσʔγϣϯ͚ͩΛՃ͢ΔRackϛυϧΣΞूOpenAPI 3.0ରԠ͕ૣ͘ɺͦͪΒʹد͍ͤͯ͘ಈ͖·͍͠• swagger-blocksͷΑ͏ͳRubyͷDSLཕ…OpenAPI 3.0ରԠ͕ݟ͑ͳ͍
JSON:APIͰͬͯΈ͍ͨ• JSONγϦΞϥΠβʔͷબ͕େࣄ• jbuilder• ActiveModel::Serializers• fast_jsonapi• rabl
JSONγϦΞϥΠβʔͷൺֱ• jbuilder• DSL͕͍·͍ͪ• ͘ͳ͍• ActiveModel::Serializers• ྑ͘ѱ͘σϑΝΫτελϯμʔυ• ϓϩδΣΫτ͕ಈ͍͍ͯͳ͍• 0.10.xͰ೩͑ਚ͖ͨʁ
JSONγϦΞϥΠβʔͷൺֱ• fast_jsonapi• Netflixɺͯ͘Αͦ͞͏• JSON:APIʹدͤͨσϑΥϧτ• AMSʹ͍͍ۙ৺• ొ৽͍͕͠ɺ͞΄Ͳ։ൃ͕׆ൃͱ͍͏Θ͚Ͱͳ͍• rabl• Ϟσϧʹର͢ΔserializerɺͰͳ͘ϏϡʔςϯϓϨʔτɺίϯϙʔωϯτܕ• චऀ͕͍׳Ε͍ͯΔ
Rabl• RubyʹΑΔDSLͱ͍͏ͷଞͱಉ͡• RailsͷϏϡʔͱͯ͠ಈ͘• JSONΛੜ͢ΔςϯϓϨʔτ (*.json.rabl)• ଞͷγϦΞϥΠβʔجຊతʹϞσϧͱJSONදݱ͕1:1͕ͩɺRablίϯςΩετʹԠͯࣗ͡༝ʹςϯϓϨʔτΛબͼɺదٓpartialͰऔΓࠐΊΔ• OpenAPIͷcomponentsͰϞσϧΛఆٛͯ͠$refͰࢀরɺͱ͍͏Ϟσϧͱ૬ੑྑ͍ͣ• rabl-railsΛ͏ͱ݁ߏ͍
rabl-rails• rablຊՈRailsʹରԠ͍ͯ͠Δ͕ɺςϯϓϨʔτΤϯδϯͱͯ͠rablΛ͍ͭͭɺίϯύΠϧͱల։ͷεςʔδΛ͚ͯੑೳΛେ෯ʹ্͛Δrabl-railsͱ͍͏gem͕͋Δ• ͜ΕͦͷΈ্ɺΠϯελϯεมΛͦͷ··͑ͳ͍ͳͲॻ͖ํ͕গ͠มΘΔ• rablຊՈͷWikiͳͲͷྫΛಡΈସ͑ɾॻ͖͑Δඞཁ͕ग़ͯ͘Δ
rablͱlayout• rablRailsͷϏϡʔͱͯ͠ಈ͘ɺͱ͍͏͜ͱJSON:APIʹԊͬͨΨϫΛlayoutͱͯ͠࡞Εɺฦ͍ͨ͠dataΛهड़͢Δ͚ͩͰࣗಈతʹԠ͕࡞Εͯศར…ʂ• ͱࢥ͍͖ɺrablͷDSL࣮ͱRubyͷߏจ্ͷ੍͔ΒςϯϓϨʔτʹyieldΛஔ͘ͱจ๏Τϥʔʹͳͬͯ͠·͏• ͭ·ΓrablͰlayoutΛॻ͘͜ͱͰ͖ͳ͍…• erbhamlΛ͑Ͱ͖Δ͕ॻ͖৺ྑ͘ͳ͍• layout͍͍ͤͥยखͰΓΔఔͳͷͰΛͭͿΖ͏…
࣮ྫ
࣮ྫ• committeeͱrablͰ࡞ͬͯΈ·ͨ͠• https://github.com/knu/jsonapi-example• ԠόϦσʔγϣϯ• ։ൃڥͷΈͰ༗ޮԽ• ςετڥͰrequest specͰ໌ࣔతʹassertionΛೖΕΔ༗ޮԽͯ͠͠·͏ͱHTTPεςʔλεͷ࣌Ͱ͚ͯ͜͠·͍ͬͯͮΒ͍• ϓϩμΫγϣϯڥͰςετΛ௨͍ͬͯΔͣͳͷͰɺ࿙Εͷ෦ͰϋʔυΤϥʔʹͳͬͯࠔΔݕ͚ͩͰ͖Δػೳ ͕४උதͳͷͰɺ࣮͞ΕͨΒ͏ͱΑͦ͞͏• JSONϏϡʔΨϫlayoutɺΤϯυϙΠϯτͷςϯϓϨʔτɺcomponentʹରԠͨ͠partialɺͱOpenAPIఆٛʹԊͬͯ࡞• ࡉ͔͍ͱ͜ΖͰɺJSON:APIͷMIME type (application/vnd.api+json)Λ͏Α͏ʹͨ͠
ײOpenAPIɺSwagger 2.0͔ΒҠߦͰ͖ͳ͍πʔϧ͕ଟͦ͏͕ͩɺҰ͔Β͏ʹ͍উखྑ͍JSON:APIʹ͍ͭͯɺ४ڌ͕Ͳͷ͘Β͍͏Ε͍͔͠Θ͔Βͳ͍Ұํɺ࣮JSON:APIରԠΛ͏ͨ͏γϦΞϥΠβ͔ɺrablͷΑ͏ʹॊೈੑͷߴ͍ͷΛΘͳ͍ͱ໘JSON SchemaͰஸೡʹॻ͍࣮ͯͱ྆ํϝϯςφϯε͢ΔͷͭΒ͍…