Rilas7.1.3 Grapeとgrape-entityを使ってサクッとAPIを作成
はじめに
Grapeは、RubyでRESTful APIを簡単に作成するためのフレームワークです。
この記事では、「Grape」と「grape-entity」を使ってAPIを簡単に作成する方法をサクッとご紹介します。
※Grape導入のため、モデルの作成、データの作成、テスト部分は省略します。以下の記事でモデルの作成、データの作成、テストの導入部分を記述しています。参考程度に読んでみて下さい。
実行環境
- M2 mac mini
- Rails 7.1.3
- Ruby 3.2.3
- Mysql 8.0
- Docker 25.0.2
- vscodeエディタ
環境構築が済んでいない方はこちらを参考に環境構築を行なってください。
Schemafileの導入がまだの方はこちらから設定してください。
RSpecの導入 ※こちらは導入しなくてもOKです。
Grape、corsをgemファイルに追加
# cors設定
gem 'rack-cors', '~> 2.0', '>= 2.0.1'
# Web APIフレームワーク
gem 'grape', '~> 2.0'
gem 'grape-entity', '~> 1.0'
追加したGemをインストール
docker-compose exec web bundle install
CORSの設定
※ここの設定がなくてもAPIは動くと思います。また設定が間違っている可能性があります。
# Cors設定
config.middleware.use Rack::Cors do
allow do
origins "*"
resource "*", headers: :any, methods: [:get, :post, :put, :delete, :options]
end
end
require_relative "config/environment"
require 'rack/cors'
use Rack::Cors do
allow do
origins '*'
resource '*', headers: :any, methods: [:get, :post, :put, :delete, :options]
end
end
run Rails.application
Rails.application.load_server
フォルダ&ファイルの作成
mkdir app/api && mkdir app/api/v1
touch app/api/root.rb && touch app/api/v1/{root.rb,tasks.rb}
config/initializers/inflections.rbの編集
apiフォルダがApiと認識されるため、APIとなるようにする。
ActiveSupport::Inflector.inflections(:en) do |inflect|
inflect.acronym "API"
end
APIの作成
module V1
class Tasks < Grape::API
resource :tasks do
desc 'タスクの一覧取得'
get '' do
tasks = Task.all
present tasks
end
end
end
end
app/api/tasks.rbをapi/v1/root.rbのRootに紐づける
module V1
class Root < Grape::API
version 'v1', using: :path
format :json
content_type :json, 'application/json;charset=UTF-8'
mount V1::Tasks
end
end
app/api/root.rbにv1で作成したRootを紐づける
class Root < Grape::API
prefix 'api'
# api/v1/root.rbをマウント
mount V1::Root
end
config/routes.rbに作成したAPIのroutesを追加
Rails.application.routes.draw do
# api/root.rbをマウント
mount Root => '/'
end
ルート確認
※通常rails routes
コマンドのルートの確認を行いますが、grapeの場合作成したAPIのroutesは出力されません。
そのためrakeファイルを作成し、作成したAPIのルートを出力するコードを記載します。
rakeファイルの作成
touch lib/tasks/grape.rake
lib/tasks/grape.rakeの編集
以下、作成したAPIを出力するコードになります。
namespace :grape do
task :routes => :environment do
Grape::API.subclasses.each do |subclass|
subclass.routes.each do |e|
puts "%-10s %-6s %-24s %s" % [subclass, e.request_method, e.path, e.description]
end
puts
end
end
end
routesの確認
docker-compose exec web bundle exec rake grape:routes
http://localhost:3001/api/v1/tasks
※設定しているポート番号でAPIを叩いてくだい。またレスポンスがエラーになる場合はコードが間違っているか、またはDockerが動作しているか確認してください。
PostmanでAPIを確認
※ブラウザ上で上記のURLにアクセスしても確認できます。
データを取得できたことが確認できました。
次に「grape-entity」を使用して取得したデータを整形し、欲しいデータを取得できるようにします。
フォルダとファイルの作成
mkdir app/api/entitys
touch app/api/entitys/task.rb
app/api/entitys/task.rbの編集
今回はid
、title
、content
、is_completed
を返すEntity
を作成します。
module Entitys
class Task < Grape::Entity
expose :id, documentation: { type: 'Integer' } # id
expose :title, documentation: { type: 'String' } # タスクのタイトル
expose :content, documentation: { type: 'String' } # タスクの内容
expose :is_completed, documentation: { type: 'boolean' } # 完了、未完了フラグ
# expose :created_at, documentation: { type: 'DateTime' } # 作成日時
# expose :updated_at, documentation: { type: 'DateTime' } # 更新日時
end
end
app/api/v1/tasks.rbの修正
タスクの一覧取得
、タスクの詳細取得
、タスクの作成
、タスクの更新
、タスクの削除
を追加&修正を行います。
module V1
class Tasks < Grape::API
resource :tasks do
desc 'タスクの一覧取得', { success: { model: Entitys::Task }, is_array: true }
get '' do
tasks = Task.all
present tasks, with: Entitys::Task
end
desc 'タスクの詳細取得',{ success: { model: Entitys::Task } }
params do # パラメータの定義
requires :id, type: Integer, description: 'ID'
end
get '/:id' do
task = Task.find(params[:id])
present task, with: Entitys::Task
end
desc 'タスクの作成',{ success: { model: Entitys::Task } }
params do # パラメータの定義
requires :title, type: String, description: 'タスクのタイトル'
requires :content, type: String, description: 'タスクの内容'
end
post '' do
task = Task.create(title: params[:title], content: params[:content])
present task, with: Entitys::Task
end
desc 'タスクの更新',{ success: { model: Entitys::Task } }
params do # パラメータの定義
requires :id, type: Integer, description: 'ID'
optional :title, type: String, description: 'タスクのタイトル'
optional :content, type: String, description: 'タスクの内容'
optional :is_completed, type: Boolean, description: '完了、未完了フラグ'
end
put '/:id' do
task = Task.find(params[:id])
task.title = params[:title] if params[:title]
task.content = params[:content] if params[:content]
task.is_completed = params[:is_completed] if params[:is_completed]
task.updated_at = DateTime.now
task.save
present task, with: Entitys::Task
end
desc 'タスクの削除',{ success: { model: Entitys::Task } }
params do # パラメータの定義
requires :id, type: Integer, description: 'ID'
end
delete '/:id' do
task = Task.find(params[:id])
task.destroy
present task, with: Entitys::Task
end
end
end
end
API確認
http://localhost:3001/api/v1/tasks
※設定しているポート番号でAPIを叩いてくだい。またレスポンスがエラーになる場合はコードが間違っているか、またはDockerが動作しているか確認してください。
最後にルートの確認
docker-compose exec web bundle exec rake grape:routes
まとめ
Grapeとgrape-entityを活用すれば、RESTful APIを簡単に、効率的に開発できます。ぜひ本記事を参考に、API開発に挑戦してみてください。
Discussion