LoginSignup
36
39

More than 5 years have passed since last update.

Sinatra + ActiveRecord = APIサーバー

Posted at

Sinatra + ActiveRecord = APIサーバー

SinatraでActiveRecordを使って簡単なAPIサーバーを作る。
今ではありきたりな組み合わせだが、やってみると案外ハマってしまう箇所もあったのでメモとして残しておく。

環境構築

Rubyのinstallは環境ごとに違うので省略

Rubyは入った前提で進める。Rubyのインストールは、rbenv経由で入れると良い。
なお、Rubyのバージョンは2.2.2以上にすること(ActiveRecordのバージョンの都合上、2.2.1以下では上手く動作しなかった。)

ターミナルにて以下のコマンドを入力

$ mkdir <project-name>
$ cd <project-name>
$ gem install bundler # gemインストール用
$ rbenv rehash # 上のインストール内容を適用する

以下の手順では、上で作成した<project-name>のディレクトリ内で作業していく

最終的なディレクトリ構造

$ tree
.
├── Gemfile
├── Gemfile.lock
├── Rakefile
├── app.rb
├── db
│   ├── migrate
│   │   └── 20160808141848_create_posts.rb
│   └── schema.rb
└── models
    └── post.rb

手順1)必要なgemをインストール

Gemfileを作成

source "https://rubygems.org"

gem "rake"
gem "sinatra"
gem "activerecord"
gem "sinatra-activerecord"
gem "sqlite3"

ターミナルにて以下のコマンドを入力して必要なgemをインストール

$ bundle install

手順2)ActiveRecordのモデルを作成する

Rakefileの作成〜DBのマイグレーション

Rakefileを作成する

require 'sinatra/activerecord'
require 'sinatra/activerecord/rake'

これで、rakeコマンドが使用可能になる。

ターミナルにて以下のコマンドを入力
NAME=~~~~の部分には、作成したいテーブル名(複数形)を記入する。

$ bundle exec rake db:create_migration NAME=create_posts
db/migrate/20160808141848_create_posts.rb

実行すると、db/migrate/20160808141848_create_posts.rbみたいなファイルが出来ている。
作成されたファイルを開いて以下のように書き込む

db/migrate/20160808141848_create_posts.rb
class CreatePosts < ActiveRecord::Migration
  def change
    create_table :posts do |t|
      t.string :title
      t.string :content
      t.timestamps
    end
  end
end

create_table :table_nameと書くことで新しいDBのテーブルを作成する。table_nameには、複数形の単語で書くこと。
また、t.string :titleのように書くことで、上記のテーブル内にカラムを追加することが出来る。この場合、string型でtitleという名前のカラムを追加することになる。

models/post.rbというファイルを作って、以下のように書く。
さっき作ったテーブルがpostsなので、モデル名はPostと単数形になる。

models/post.rb
ActiveRecord::Base.establish_connection('sqlite3:///model.db')
class Post < ActiveRecord::Base 
end

Rakefileも編集しておく。 models/post.rb を読み込んで、rakeコマンドでDBと接続できるようにする。

require 'sinatra/activerecord'
require 'sinatra/activerecord/rake'
require './models/post.rb'

これでDBとの接続は完了。
ここまで来たら、ターミナルに戻って以下のコマンドを入力

$ bundle exec rake db:migrate
  class CreateUsers < ActiveRecord::Migration[4.2] (called from load at ~/.rbenv/versions/2.3.0/bin/rake:23)
== 20160808141848 CreatePosts: migrating ======================================
-- create_table(:posts, {})
   -> 0.0014s
== 20160808141848 CreatePosts: migrated (0.0015s) =============================

なんかうにゃうにゃ出てきたら成功

Sinatraでアプリを作っていく

app.rbというファイルを作って、以下のように書く。
Sinatraの書き方に関しては説明を割愛する。
ポイントは、それぞれの返り値を .to_json としてjson形式で終わらせること。

app.rb
require "sinatra"
require "sinatra/activerecord"
require "./models/post.rb" # さっき作ったモデルを読み込み

get "/posts" do
  Post.all.to_json # 全てのPostを返す
end

get "/posts/:id" do
  Post.find(params[:id]).to_json # :idのPostを返す
end

post "/posts" do
  # sinatraはPOSTメソッドの際デフォルトでjsonを受け取れないので変換
  # 参考: http://qiita.com/izumin5210/items/caf66ece1f67a0fd6a4c
  json = JSON.parse(request.body.read)
  post = Post.new(json)
  if post.save
    { result: "success", code: 200 }.to_json
  else
    { result: "failure" }.to_json
  end
end

ここまで書けたら、ターミナルでSinatraサーバーを起動する

$ ruby app.rb

作ったアプリを試してみる

Sinatraのデフォルトポートは4567なので、localhost:4567に対してcurlでアクセスしてみる。

$ curl http://localhost:4567/posts
[]

$ curl -XPOST -d '{"title": "dummy title", "content": "dummy content"}' http://localhost:4567/posts
{"result":"success","code":200}

$ curl http://localhost:4567/posts
[{"id":1,"title":"dummy title","content":"dummy content","created_at":"2016-08-08T14:52:07.086Z","updated_at":"2016-08-08T14:52:07.086Z"}]

$ curl http://localhost:4567/posts/1
{"id":1,"title":"dummy title","content":"dummy content","created_at":"2016-08-08T14:52:07.086Z","updated_at":"2016-08-08T14:52:07.086Z"}

正常に動作していることを確認。お疲れさまでした。

終わりに

今回作成したプロジェクトはこちら。
https://github.com/litmon/sinatra-api

rubyのバージョンが2.2.1以下だと、ActiveRecordのバージョン5.0.0が導入できない。
そのせいで、モデルのデータをDBから引っ張ってくるときにエラーになって何十分かハマってしまった。
ActiveRecordのバージョンをもう少し下げれば上手くいくかもしれないな……要調査。

36
39
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
36
39