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

YAPC::Hokkaido

120b74af626c2b23f954926ef68ac5d6?s=47 papix
December 10, 2016

 YAPC::Hokkaido

120b74af626c2b23f954926ef68ac5d6?s=128

papix

December 10, 2016
Tweet

Transcript

  1. APIをPerlで作る時に 僕達が考えたこと by papix 〜 2016/12/10 YAPC::Hokkaido 〜

  2. お前誰よ?

  3. papix
 Perl/Go/Infra Engineer
 @ _ _ p a p i

    x_ _ https://twitter.com/__papix__ papix https://github.com/papix Masteries (TECH) http://papix.hatenablog.com/ adish •  Engineer Perl Entrance (Headmaster)
 Mackerel User Group (Founder) 346 Production (Producer / 渋⾕凛担当) 絶対笑顔でまだまだ いっぱい夢みるブログ (LIFE) http://papix.hatenablog.jp/
  4. はじめに

  5. このトークの対象は? •  APIをめっちゃ書いてる⼈ •  どんどんマサカリを投げましょう! •  APIを書いていない⼈, 学⽣さん •  APIを書くという仕事の⼀例が⾒れます

  6. もくじ •  はじめに •  あらすじ 〜 今回の題材 •  そもそもAPIって? • 

    PerlでAPIを作ろう! •  APIの仕様を定める •  APIをドキュメント化する •  さいごに
  7. あらすじ

  8. あらすじ •  Gaiax/adishの場合, 中⼩規模のサービスが多い •  Ruby, PHP, Perlを使ったMonolithic App • 

    Perlであれば, Amon2で… Xslateで描画… •  そこまでしっかりAPIを作る機会はなかった •  そんな⼈達がMicroservice… のようなもの… に⼿を出したら? •  その体験や失敗談をお話します •  是⾮他⼭の⽯に…
  9. 今回の題材

  10. 題材: hitobo •  adishの新サービス •  adishの強み(⼈⼒運⽤)とBotの連携によるCS •  問い合わせの最初はBotが対応 •  必要に応じて,

    ⼈間に切り替わる •  Botの導⼊によって, 次のような効果を狙う •  対応までの速度の向上 •  CSを提供するコストの低減
  11. hitobo開発チーム •  9⼈チーム •  プロダクトオーナー 兼 営業 x1 •  営業

    x1 •  運⽤担当 x3 (CS対応) •  エンジニア x3 •  スクラムマスター x1
  12. hitoboのアーキテクチャ •  複数のComponentがAPIで連携している

  13. hitoboのアーキテクチャ •  Fluxっぽい!

  14. hitoboのアーキテクチャ •  ところで, 各Componentの実装⾔語は?

  15. hitoboのアーキテクチャ •  ところで, 各Componentの実装⾔語は? Node Node Python Ruby Perl

  16. !?

  17. 3開発者 / 4⾔語

  18. どうしてこうなった…

  19. どうしてこうなった… •  Gaiaxにおける技術戦略 •  各事業/各⼦会社が技術戦略を⽴てて実践 •  hitoboのエンジニアは移籍組が多い •  papix: Perlのチームから移籍

    •  A⽒: PHPのチームから移籍 •  機械学習のために今はPython •  B⽒: Rubyのチームで開発 (当初からadish)
  20. どうしてこうなった… •  当初は「みんなでRubyを勉強しながら作ろう!」 •  ところが… •  「この界隈, レッドオーシャンで時間に余裕が まったくない!」 • 

    「ウッス」 •  「だからまずは作ろう!」 •  「アッハイ」
  21. こうして… •  各Componentが連携する必要がある •  APIを使って連携!!! •  結果として… •  名状し難いMicroserviceのようなものが… • 

    とはいえ, そもそも, APIの実装や連携は難しい •  Monolithicに作れるならその⽅が良かった!!!!!
  22. ちなみに… •  あるComponentが担うRDBMSを操作する場合, 次のようにAPIを介して⾏うことになる •  「そうだ! APIではなくDBを介して連携しよう!」 Component A Component

    B RDBMS Read/Write Read/Write Component A Component B RDBMS Read/Write API
  23. 「そうだ! APIではなくDBを介して連携しよう!」 •  やめろ!!! ⾟いぞ!!!!!!!! •  RDBMSのSchemaのMigrationが⾮常に難しい •  Component A/Bともに新しいSchemeに対応

    しなければならない •  → 同時にデプロイする必要がある •  → Component分ける意味がないじゃん •  MonolithicなApplicationで良い!!!!!
  24. そもそもAPIって?

  25. そもそもAPIって? •  Application Programming Interface •  Componentが相互に連携するために⽤いる Interface

  26. 例えば… (MackerelのAPIドキュメント) •  MackerelのAPIドキュメント:

  27. 例: Request (MackerelのAPIドキュメント) •  APIにHTTPでRequestを送る •  URIで「何を操作するか(Resources)」を⽰す •  Methodで「どう操作するか(Action)」を⽰す • 

    次のAPIはhostsを(URI), 取得する(Method)もの URI(Endpoint) Method
  28. 例: Response (MackerelのAPIドキュメント) •  Requestに対してAPIはResponseを返す •  次の例では, JSONでResponseが返る •  Requestによっては,

    エラーが返ることも
  29. 外部向けAPIと内部向けAPI •  APIを「誰が使うか」で分類すると… •  外部向けAPI •  Serviceを使う利⽤者に提供するAPI •  先ほどのMackerelのAPIもこれ • 

    内部向けAPI •  Serviceの内側で使うAPI •  Serviceの開発者が開発し, 開発者が使う
  30. 外部向けAPIと内部向けAPI •  「内部向けAPI」を作る機会は増えてきている •  Single Page Application, スマホアプリ… •  MicroserviceによるComponent連携

    •  Monolithicに作れるならその⽅が良いが… •  うまくAPIでComponentを分割することで, 実装をシンプルに出来る場合もある
  31. 例: はてなブックマーク http://www.slideshare.net/oarat/2015-0801-scala

  32. 例: はてなブックマーク •  ScalaのAPI ServerとPerlのView Server •  後段のAPI Serverでデータを扱う • 

    Scalaの特徴を活かして堅牢に •  前段のView ServerでHTMLの描画 •  ユーザー向けのViewを提供 •  双⽅の良さを活かした開発ができそう!
  33. APIを作る難しさ •  APIの更新は難しい •  「外部向けAPI」は, 利⽤者に変更へ追随して もらう必要がある •  当然, 変更を強いれないのでVersioning

    しなければならない •  「内部向けAPI」も同様... •  内部の開発者が使うので変更への対応は し易いとはいえ, コストは必要
  34. APIを作る難しさ •  最初にしっかり仕様を決める必要がある •  最初に雑に作ると, 後で変更するのが⼤変! •  参考にできるものを参考にしていく •  「Web

    API: The Good Parts」 •  既存のAPIとその仕様
  35. APIの仕様を決める時に役⽴つもの •  「Web API: The Good Parts」

  36. APIの仕様を決める時に役⽴つもの •  既存のAPIとその仕様 •  「Web API: The Good Parts」にも書かれてる • 

    以前外部APIを設計したときは, GitHubや QiitaのAPI仕様を参考にしたり… •  とはいえ, APIごとの特徴, 癖もある •  完全にコピーせず, 開発しているServiceに 適したものを組み上げていくのが⼤事
  37. PerlでAPIを作ろう!

  38. WAFやORMは? •  ぶっちゃけ何でも… •  WAFなら, Amon2, Mojolicious, Catalyst… •  ORMなら,

    Teng, Aniki, DBI… •  個⼈的には, Amon2 + Anikiをよく使います •  どちらもHackしやすくて楽しい!!!
  39. 気をつけよう: JSONのデータ型 •  Perlは⽂字列と数値の扱いがゆるふわ •  無意識に実装していると, ⽂字列/数値で返す べきところを数値/⽂字列で返したりする •  JSON::Typesで型を強制できる

    •  真偽値はJSON::true / JSON::false で!
  40. テストは? •  普通にAPI Serverを起動してテストする •  HTTPのRequestを投げて, 期待する Responseが返ってくるかどうか? •  Sessionを考慮しなくて良いので楽ではある

    •  Response(例えばJSON)を期待値と⽐較すれば 良いので, 検証もしやすい
  41. APIの仕様を定める

  42. APIの仕様を定める •  ここがAPI開発のキモ •  ⼀度公開したAPIの仕様変更は簡単ではない •  APIの仕様をしっかり設計しないといけない

  43. 基本ルールを定める •  APIの根本的なルールを定める •  具体的な仕様はこのルールに則って決める •  Request/ResponseのFormat •  ResourcesのFormat • 

    HTTPのStatus Code •  URIの決め⽅ •  既存のAPIが基本ルール策定に⾮常に役⽴つ!
  44. ⼀度決めたルールは守っていくのが基本 •  後々「悪⼿だった…」と気づいたとしても! •  同じVersionのAPIで複数のルールに従った APIが存在すると, 提供側も利⽤側も困惑… •  基本ルールの変更は新しいVersionのAPIで • 

    旧VersionのAPIは⾮推奨(Depricated)に •  最新VersionのAPIでも, より良いAPIが提供 された場合⾮推奨にしておくと良い
  45. APIを通して何を提供するかを決める •  APIの利⽤者が, APIを使ってServiceに対して どのような操作を⾏いたいか? •  基本は, これを満たすAPIを実装していけば良い •  「外部向けAPI」の場合,

    開発者で機能/仕様を相談 して決定し, 実装していくことになる
  46. 「内部向けAPI」の場合… •  APIの種類(?)によって考え⽅は変わる

  47. 複数のServiceが利⽤する社内基盤的APIなら… •  分類としては「内部向けAPI」 •  しかし, 「外部向けAPI」と考え⽅は近くなる •  汎⽤的なAPIを設計して提供する

  48. 単⼀Service内でのみ利⽤するAPIなら… •  「APIを使う側」が使いやすいように •  APIを利⽤する, JavaScriptやスマホアプリの 実装者が仕様のベースを決めると楽 •  API提供側が決めると漏れがあったり過剰になる • 

    JS/スマホアプリを実装するにあたって, 必要最低限のAPIを提供していく
  49. APIをドキュメント化する

  50. APIをドキュメント化する •  ⾔うまでもなくドキュメント化は⾮常に重要!!!

  51. 外部向けAPIの場合… •  利⽤者にAPIを使ってもらう為に必須! •  GitHubやMackerel, Qiitaのドキュメントは ⾮常によくできていて勉強になります

  52. 内部向けAPIの場合… •  APIを使う開発者が使いやすいように •  「コードを読めばわかる」は確かに真 •  チームとしてはそれが出来るのが理想 •  とはいえ毎度それをするのは⾮効率 • 

    開発がスムーズに進むように, チームに⼊った⼈ がシュッと理解出来るように… •  APIの基本ルール/仕様をドキュメントに!
  53. APIをドキュメント化する⽅法 •  次のような⽅法があります: •  APIの仕様を定義する仕組みを使う •  実装からドキュメントを作る仕組みを使う •  Wikiなどに頑張って書いていく

  54. ①APIを定義する仕組みを使う •  いろいろ提供されている •  Swagger •  JSON Schema •  APISchema

    •  Swagger/JSON Schemaはよく知られている •  ググればQiitaとかで無限にサンプルがある •  ので, 今回はAPISchemaを紹介します!
  55. APISchema •  hitode909さん製 •  PerlのDSLでAPIの仕様を定義 •  次の機能を提供 •  Routerの⾃動⽣成 • 

    Request/Responseに対するValidation •  Schemeから仕様のMarkdown⽣成 •  PlackのMiddlewareとして提供
  56. APISchemaでのResources定義

  57. APISchemaでのEndpoint定義

  58. 定義したSchemeを利⽤する

  59. メリデメ •  メリット •  ちゃんと仕様が定められている •  エコシステムが整っている •  デメリット • 

    初期の学習コストが若⼲⾼い •  …が, 最終的にしっかりやっていく必要が あるので, 最初から頑張っておいて良さそう!
  60. ②実装からドキュメントを作る仕組みを使う •  ⾔語ごとにいろいろ提供されています •  autodoc (Ruby) •  Test::JsonAPI::Autodoc (Perl) • 

    Test::JSON::RPC::Autodoc (Perl) •  Test::JsonAPI::Autodocを簡単に紹介します
  61. APIを使ったテストを書く

  62. テストを実⾏すると, ドキュメントが⽣成される

  63. メリデメ •  メリット •  テストを書けばドキュメントが出来る •  デメリット •  逆に⾔えば実装を先にしなければならない • 

    実装前に仕様案をドキュメント化して, 共有 したり相談するのは難しい •  「テストファースト」でテストを先に作り, 共有するという⼿はあるが…
  64. ③Wikiなどに書く •  GitHubやBitBucketのWiki, esa.io …

  65. メリデメ •  メリット •  導⼊はしやすい(理解しやすい) •  最初の⼀歩はこれ? •  デメリット • 

    Machine Readableではない •  ドキュメントの書きやすさがSaaS/ツールに 左右されてしまう
  66. ドキュメントを更新し続ける •  APIの「仕様」と「実装」が⼀致しているかを確認 •  これを確認するテストを書ければ… •  そのためには, 仕様をMachine Readableに するのが必須になってくる

    •  APIのドキュメントを更新するチーム作り •  若⼲精神論っぽい…! •  とはいえ, これを作るのが最優先 •  確認する仕組みは, あくまでこれの補助
  67. さいごに

  68. さいごに •  APIに関する様々な話題について紹介しました •  APIを利⽤したServiceの構築例 •  APIについての簡単な紹介 •  APIを作る為に有⽤なライブラリの紹介 • 

    「内部向けAPI」は毒にも薬にもなる •  うまく役割/機能を分離できるかもしれない •  しかし, 異様に複雑にしてしまう可能性も…
  69. Any Questions?