概要
grape は RESTful な API を構築するためのフレームワークです
DSL を使うことで簡単に RESTful API を構築することができます
今回は基本的に GET/POST/DELETE/PUT の API を grape で構築してみたので紹介します
環境
- macOS 10.15.6
- Ruby 2.7.1p83
- grape 1.4.0
インストール
bundle init
vim Gemfile
gem "grape"
bundle config path vendor
bundle install
Getting Started
とりあえず超簡単なサンプルを作成してみます
vim app.rb
require 'grape'
module Test
class API < Grape::API
format :json
prefix :api
resource :blog do
desc 'Return an article.'
get :article do
{
"title" => "title",
"body" => "body"
}
end
end
end
end
vim config.ru
require './app'
Test::API.compile!
run Test::API
bundle exec rackup config.ru
記事を取得するリクエストは以下のようになります
localhost:9292/api/blog/article
とりあえずは単純な JSON が返ってくるだけです
ここから POST や DELETE, PUT の API を追加していきます
POST の追加
まずは記事を追加できる機能を作ってみます
本来ならデータベースで管理したほうが良いですが今回はテストなのでメモリ上で管理します
require 'grape'
module Test
class API < Grape::API
format :json
prefix :api
articles = []
resource :blog do
desc 'Return an article.'
get :article do
articles
end
desc 'Create new article.'
params do
requires :title, type: String, desc: 'An article title'
requires :body, type: String, desc: 'An article body'
end
post do
articles.append({
title: params[:title],
body: params[:body]
})
end
end
end
end
articles という配列を変数として管理し POST 時にその配列に追加していきます
必須パラメータは requires
を使います
必要なパラメータ分 requires
しタイプとパラメータの説明を付与します
実際に処理をするブロック内でパラメータを参照する場合は params[:title]
という感じで取得します
記事を登録するリクエストは以下のようになります
curl -XPOST -H 'Content-Type: application/json' -d '{"title":"First article","body":"Today is sunny"}' localhost:9292/api/blog
また記事を GET する API も articles をそのまま返却するようにします
DELETE の追加
次に記事を削除する API を追加します
今回は配列のインデックスで削除できるようにしてみます
require 'grape'
module Test
class API < Grape::API
format :json
prefix :api
articles = []
resource :blog do
desc 'Return an article.'
get :article do
articles
end
desc 'Create new article.'
params do
requires :title, type: String, desc: 'An article title'
requires :body, type: String, desc: 'An article body'
end
post do
articles.append({
title: params[:title],
body: params[:body]
})
end
desc 'Delete an article.'
params do
requires :index, type: Integer, desc: 'An article index'
end
delete ':index' do
error!("Does not found index", 404) if articles[params[:index]].nil?
articles.delete_at(params[:index])
end
end
end
end
記事を削除するリクエストは以下のようになります
curl -XDELETE localhost:9292/api/blog/0
もし指定のインデックスが存在しない場合には {"error":"Does not found index"}
が返ってきます
:index
のように URI からパラメータを受け取る場合には delete ':index'
という感じで引数に指定します
こうすることでブロック内で params[:index]
として値を受け取ることができるようになります
PUT の追加
最後に更新の API を作ってみましょう
これまで実装してきた POST や DELETE の機能を組み合わせる感じになります
require 'grape'
module Test
class API < Grape::API
format :json
prefix :api
articles = []
resource :blog do
desc 'Return an article.'
get :article do
articles
end
desc 'Create new article.'
params do
requires :title, type: String, desc: 'An article title'
requires :body, type: String, desc: 'An article body'
end
post do
articles.append({
title: params[:title],
body: params[:body]
})
end
desc 'Delete an article.'
params do
requires :index, type: Integer, desc: 'An article index'
end
delete ':index' do
error!("Does not found index", 404) if articles[params[:index]].nil?
articles.delete_at(params[:index])
end
desc 'Update an article.'
params do
requires :index, type: Integer, desc: 'An article index'
requires :title, type: String, desc: 'An article title'
requires :body, type: String, desc: 'An article body'
end
put ':index' do
error!("Does not found index", 404) if articles[params[:index]].nil?
articles[params[:index]] = {
title: params[:title],
body: params[:body]
}
end
end
end
end
PUT のリクエストは以下のようになります
curl -XPUT -H 'Content-Type: application/json' -d '{"title":"Third article","body":"It is cloudy"}' localhost:9292/api/blog/0
DELETE と同様で index がない場合にはエラーにしています
helpers メソッドを使う
helpers
メソッドはブロック内に定義したメソッドを各 API で使うことができる機能です
各 API での共通処理などを記述しておきます
例えば認証機能などを各 API に付与したい場合には以下のように使えます
require 'grape'
module Test
class API < Grape::API
format :json
prefix :api
articles = []
@username = ""
http_basic do |username, password|
@username = username
end
helpers do
def authenticate
error!('Unauthorized', 401) unless @username == "admin"
end
end
resource :blog do
desc 'Return an article.'
get :article do
authenticate
articles
end
end
end
end
ベーシック認証で特定のユーザ名やパスワードでないとアクセスできないようになります
helpers
内で変数を参照する場合はインスタンス変数にしておきましょう
最後に
grape を使って簡単な RESTful API を構築してみました
DSL なので初めは少し戸惑うかもしれませんが慣れれば簡単に使えると思います
RESTful API に必要な基本的なヘッダ処理 (Content-Type や Method) などのハンドリングがすでに実装されているのは嬉しい点かなと思います
まだ使い込んでないので何とも言えませんが REST 専用のフレームワークっぽいので HTML などを返却する場合には Rails や Sinatra などを使ったほうが良いかもしれません
ただ grape には swagger と連携したりRails と連携して REST を構築したりできる拡張機能も充実しているのでサードパーティ系のエコシステムが充実していそうな感じもします
0 件のコメント:
コメントを投稿