前提
業務でAPIの知識を身につける機会があったので、基本的な知識をまとめてみました。
目的
APIの知識がほとんどないような初心者でもAPIが作れるようになること。そのために、今回は以下のフローでAPIを作成するための知識を身につけていきます。
流れ
- Grapeを使ったRailsのAPIの書き方
- Grapeの導入方法
- RailsにおけるAPIとは
- HTTPメソッド
- APIのURI設計(エンドポイント設計)
- まとめ
Grapeを使ったRailsのAPIの書き方
今回は、こちらのサイトに書いてあるAPIコードをもとに説明をしていこうと思います。
参考: http://dev.classmethod.jp/server-side/ruby-on-rails/ruby-on-rails_create_grape_web-api/
module Twitter
class API < Grape::API
# version 'v1', using: :header, vendor: 'twitter'
version 'v1', using: :path
format :json
prefix :api
helpers do
def current_user
@current_user ||= User.authorize!(env)
end
def authenticate!
error!('401 Unauthorized', 401) unless current_user
end
end
resource :statuses do
desc "Return a public timeline."
get :public_timeline do
Status.limit(20)
end
desc "Return a personal timeline."
get :home_timeline do
authenticate!
current_user.statuses.limit(20)
end
desc "Return a status."
params do
requires :id, type: Integer, desc: "Status id."
end
route_param :id do
get do
Status.find(params[:id])
end
end
desc "Create a status."
params do
requires :status, type: String, desc: "Your status."
end
post do
authenticate!
Status.create!({
user: current_user,
text: params[:status]
})
end
desc "Update a status."
params do
requires :id, type: String, desc: "Status ID."
requires :status, type: String, desc: "Your status."
end
put ':id' do
authenticate!
current_user.statuses.find(params[:id]).update({
user: current_user,
text: params[:status]
})
end
desc "Delete a status."
params do
requires :id, type: String, desc: "Status ID."
end
delete ':id' do
authenticate!
current_user.statuses.find(params[:id]).destroy
end
end
end
end
RailsにおけるAPIとは
RailsでAPIを作るとき、MVCのような役割がAPIにもあります。
Model
これは今まで通りのRailsのmodelです。APIでメソッドを使用する際には、そのクラスに対応するモデルから呼び出します。
View
rablというものを使って、viewをかきます。APIにおけるviewとは、クライアントからエンドポイントを指定してAPIを叩かれたときに取得した情報を返すのですが、それを返す形式含め定義した場所がviewファイルに対応します。よくあるものとしては、サーバから取得した情報をハッシュとして返してあげることで、クライアント側で、その情報が使いやすいようにしてあげることがあります。
rabl
GETの一覧取得系のAPIだと取得した内容をクライアント側に返す必要があります。その場合最近だと、json形式で出力する場合がほとんどです。そんなときに便利なのが、rabl
というものです。
rablの導入方法
Gemfileに以下のものを追加してbundle install
するだけです!
gem 'rabl'
rablファイル
object false
child(@item) do
attribute :id, :name
end
{
"item": [
{
"id": 1, "name": "Test 1"
},
{
"id": 2, "name": "Test 2"
}
]
}
controller側のサンプルコードとは関係ありませんが、上記のようにしてrablファイルは使います。そして、これをPostmanというツールを使ってAPIを叩いてあげると、上記のようなレスポンスがクライアントへ返ってきます。補足ですが、APIを使用したサービスなどは、このようにAPIを叩き、返ってきたレスポンスを自社のサービスで改めて整形し、viewに出力して使っています。
Postmanとは
PostmanとはAPIを実際に叩き、レスポンスをみることができるツールです。
インストールは以下のURLからできます。
https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop
Postmanの使い方
・ まずはHTTPメソッドを選択します。今回は試しにPOSTを使ってみます。・ 次に、このようにエンドポイントをいれてあげます。そして、paramsのデータをいれてあげたあとに、「send」を押すとレスポンスを返してくれます。paramsにいれるものはAPIによってまちまちですが、例えばaccess_tokenやidなどがよくあるパターンです。
Controller
APIのコードを主にここにかきます。考え方としては、Railsのcontroller同様データのやり取りをする場所といったものです。具体例が、「Grapeを使ったRailsのAPIの書き方」にある、api.rbファイルです。APIをたたくと、パラメーターで欲しい情報が渡ってきます。そして、この渡ってきたものを使い様々な処理をします。これだけ聞くといつも通りのRailsのcontrollerと似たような機能ですよね。そして、補足ですが、strong parameterはAPIではhelpersの中に書きます。
params
APIではparamsを指定して、取得したい情報を書きます。その場合、必ず取得したいものとnilでも問題ないもののうち、どちらであるかを指定します。それが以下二つのものです。
- requires - 必ず取得しないといけないもの
- optional - nilでも問題ないもの
飛んでくるparamsは全てstringですが、ここでtypeを指定してすることで、grapesがtype変換してくれます。その具体例が以下のコードです。
params do
requires :access_token, type: String
optional :page, type: Integer
end
helpers
APIで何度も使用するものなどは(普通のcontrollerでいうstrong parameterなど)、helpers do
の中でにメソッドを定義することで何度も同じAPIファイル内で使用することができます。ただし、APIのhelpersはAPIファイルをDRYに書くためのものであるので、ControllerとModelの関係性は守り、Modelに切り出すべきものは対応するModelに書きましょう。
desc
descはそれ以下で行われている処理を端的に表現したものです。
HTTPメソッド
APIのコードを見ていると、get '/' do
などの表記を目にすることがあると思います。これが何をやっているのかAPIにおけるHTTPメソッドをみながら説明していきます。
メソッド名 | 役割 |
---|---|
GET | リソースの取得 |
POST | リソースの新規登録 |
PUT | 既存リソースの更新 |
DELETE | リソースの削除 |
PATCH | リソースの一部変更 |
GET
- 情報を取得するためのメソッド
POST
- 指定したURIにたいして新しい情報(リソース)を送信するためのメソッド。言い換えると、新しい情報を登録するために利用するメソッドといえる。
PUT
- URIの情報(リソース)が既に存在する場合、その情報を上書きするためのメソッド。かりに情報が存在しない場合、作成することも可能ではあるが、APIにおいて、その役割はPOSTにまかせることが推奨されている。
DELETE
- URIで指定した情報(リソース)を削除するためのメソッド
PATCH
- 指定したURIの既存リソースの情報を一部変更するときに使用するものです。一方、PUTメソッドは既存リソースをすべて変更する際に使用します。例えば、1MBのリソースが存在するとして、この大きなリソースの一部を変更したいときに、毎回PUTメソッドで変更していては、非効率な通信となります。そんなときに、PATCHメソッドを使うことで、より小さなデータ量をやりとりするだけですむので効率が上がります。
APIのURI設計(エンドポイント設計)
get '/' do
のGET含めHTTPメソッドで何をやりとりしているのか理解した次は、````'/'```の部分を学習しましょう。
URI(エンドポイント)とは?
APIにアクセスするためのもののことを指しています。
例えば、ECサイトにおける商品情報を取得するAPIが提供されている場合、それぞれAPIとしてアクセスするURIを持っています。このようにして、ものすごく簡単にいうと、欲しい情報を取得できる場所のことをURI(エンドポイント)といいます。
https://api.example.com/v1/users/me
良いエンドポイント設計のコツ
- 短くて入力がしやすこと
- 改造しやすいこと
- 大文字や小文字が混同せず統一されていること
- 人間が読んで理解できること
- サーバ側のアーキテクチャが反映されていないこと
- ルールが統一されていること
短くて入力がしやすいこと
これはそのままの意味ですが、長いURIにはたいてい不必要な情報が入っていることが多いです。そのような長いものだと冗長であり、ミスを引き起こしやすくします。不必要なものは削除し、シンプルで短い理解しやすいURIを作成する必要があります。
改造しやすいこと
改造しやすいURIとは、URIを修正して、別のURIにすることが容易であるということです。例えば、以下のような場合、idを変えればほかのリソースにアクセスできることが一目で想像がつきます。このように改造しやすい命名であることもAPIを作る上では、大切な考え方です。
https://api.example.com/v1/users/1
大文字や小文字が混同せず統一されていること
大文字、小文字が混じっていると、他者が使用する際にミスを引き起こしやすくします。それを避けるためにも小文字で統一するなりすべきです。
人間が読んで理解できること
APIに限らずプログラミングの世界では当たり前の考え方ですが、誰か特定の人にのみわかる命名はさけるべきでしょう。それよりも誰が見ても同じ考えになるような命名を心がけるべきという考え方です。
サーバ側のアーキテクチャが反映されていないこと
サーバ側のAPIファイルの位置をURIにしているものをたまに見かけますが、それは避けるべきです。これは一つ目のルールであった、「短くシンプルなものに」という考え方からしてもナンセンスで、不必要な情報が多くなるので避けるべきです。
ルールが統一されていること
APIを提供する場合、細かくいくつかのエンドポイントを公開する場合が、ほとんどです。その場合、それぞれのURIがばらばらの規則であるとユーザーからして非常に使いにくいため、URIはルールが統一されていることが重要です。
基本的なエンドポイントの設計
上記の規則をふまえたうえで、基本的なAPIのエンドポイント設計が以下のものです。
目的 | エンドポイント | メソッド |
---|---|---|
ユーザー一覧取得 | https://api.example.com/v1/users | GET |
ユーザーの新規登録 | https://api.example.com/v1/users | POST |
特定のユーザーの情報を取得 | https://api.example.com/v1/users/:id | GET |
ユーザー情報の更新 | https://api.example.com/v1/users/:id | PUT/PATCH |
ユーザー情報の削除 | https://api.example.com/v1/users/:id | DELETE |
まとめ
今回はAPIを作る上で、最低限の機能の説明をさせていただきました。APIを実装する上で、何から手をつけて良いかわからない方などの手助けとなれば幸いです。