今更ですが
今までフロントエンドのみ触ってきたサーバーサイドに全く触れたことのない学生が、勉強しながら書いてます。
全部完成させてこの記事を書いているわけでは無いので見通しの良い、使えるコードであるかはわかりません。ご了承ください。
僕みたいなサーバーサイド触ったこと無いけどAPI作ってみるかって人の参考に少しでもなればと思います。
ドキュメントへのタグ情報の付与
grape-entityのインストール
gem 'grape-entity'
その後bundle install
Entityを定義
これを使えば簡単に埋め込みができたり無駄なものを返さなくて良くなります
module Entities
class Tag < Grape::Entity
expose :id, :name
end
class Document < Grape::Entity
expose :id, :content, :title, :user_id, :created_at
expose :tags, using: Entities::Tag
end
end
includeさせる
desc "returns all documents"
get do
document = Document.includes(:tags)
present document, with: Entities::Document
end
これでhttp://localhost:3000/api/document
にアクセスすると
{
id: 1,
content: "ほげふがぴよ",
title: "ほげほげ",
user_id: 1,
created_at: "2015-03-17T04:08:38.185Z",
tags: [
{
id: 1,
name: "ふがふが"
}
]
}
タグ情報が含まれて帰ってきます
絞込みの実装
タグによるドキュメントの絞り込みを実装しました。
URLの指定の仕方がこれでいいのか悩みましたがとりあえずこういう形にしておきます。
class Tag_API < Grape::API
resource "tags" do
params do
requires :tag_id, type: Integer
end
# http://localhost:3000/api/tags/{:tag_id}/document
get ':tag_id/documents' do
document = Document.includes(:tags).where(tags: {id: params[:tag_id]})
present document, with: Entities::Document
# 以下だとSQLがドキュメント毎に走るN+1問題
# tag = Tag.find(params[:tag_id])
# present tag.documents, with: Entities::Document
end
end
end
コメントアウトしているようなコードで、検索してからドキュメントを返そうとするとドキュメント毎にSQLが走ってしまいます
研究室のWiki程度ならこれくらいでもいいかもしれないですが、それなりにアクセスされる何かを作る場合はお気をつけください