Ruby
MySQL
Sinatra
ActiveRecord

Sinatra+ActiveRecord+MySQLで、簡単APIサーバ構築

More than 5 years have passed since last update.

サーバを使ったiPhoneアプリを作りたかったので、簡単にサーバ側作れないか調べてみました。結論として結構簡単に出来る事が分かったのでメモメモ。


参考にした記事

Sinatra+ActiveRecord+SQLite3で,軽量なWeb-DB連携例 | tamo's blog

大分参考にさせて頂きました。ありがとうございます!

仕事ではMySQLを使う事が多いので、SQLite3ではなくMySQLを使う事にしました。


手順


  1. Ruby,MySQLをインストール

  2. データベースを作成

  3. Gemfileを作成とインストール

  4. database.ymlを作成

  5. Rubyファイルを作成

  6. 実行

  7. 動作確認


1. Ruby,MySQLをインストール

結構な量になったので別記事にまとめました。ここが一番面倒(´Д`)

- Ruby,MySQLの環境を構築する(Mac版) #MySQL #Mac #Ruby #homebrew - Qiita

- Ruby,MySQLの環境を構築する(Linux版) #MySQL #Ruby #Linux - Qiita


2. データベースを作成

MySQLの初歩的なコマンドを知っていれば、ここは問題ないと思います。

ActiveRecordの流儀で、テーブル名は複数形にする必要がある事だけ注意!

サンプルとして、タイトル, 詳細文, 作成日時, 更新日時を持つ、topicsテーブルを生成してみます。

mysql> create database hoge;

Query OK, 1 row affected (0.00 sec)

mysql> use hoge
Database changed

mysql> create table topics (
-> id INT UNSIGNED NOT NULL AUTO_INCREMENT,
-> title VARCHAR(255) NOT NULL,
-> description VARCHAR(255) NOT NULL,
-> created_at DATETIME NOT NULL,
-> updated_at DATETIME NOT NULL,
-> PRIMARY KEY(id)
-> );
Query OK, 0 rows affected (0.03 sec)

mysql> desc topics;
+-------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| title | varchar(255) | NO | | NULL | |
| description | varchar(255) | NO | | NULL | |
| created_at | datetime | NO | | NULL | |
| updated_at | datetime | NO | | NULL | |
+-------------+------------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)


サンプルデータを登録

動作確認をする為のサンプルデータを入れておきます。

mysql> insert into topics values(1, "title1", "description1", now(), now());

Query OK, 1 row affected (0.00 sec)

mysql> insert into topics values(2, "title2", "description2", now(), now());
Query OK, 1 row affected (0.01 sec)

mysql> insert into topics values(3, "title3", "description3", now(), now());
Query OK, 1 row affected (0.00 sec)

mysql> select * from topics;
+----+--------+--------------+---------------------+---------------------+
| id | title | description | created_at | updated_at |
+----+--------+--------------+---------------------+---------------------+
| 1 | title1 | description1 | 2013-05-19 21:29:21 | 2013-05-19 21:29:21 |
| 2 | title2 | description2 | 2013-05-19 21:29:29 | 2013-05-19 21:29:29 |
| 3 | title3 | description3 | 2013-05-19 21:29:38 | 2013-05-19 21:29:38 |
+----+--------+--------------+---------------------+---------------------+
3 rows in set (0.01 sec)


3. Gemfileを作成とインストール

次に、使用するgemファイルを管理するファイルを作ります。

# ひな形ファイルの作成

$ bundle init
Writing new Gemfile to /home/u1/hoge/Gemfile

# 編集
$ vi Gemfile
source "https://rubygems.org"

gem "activerecord"
gem "mysql2"
gem "sinatra"

# 必要なGemのインストール
$ bundle install --path vendor/bundle

ActiveRecordとMySQLを使うのでそれぞれのgemを記入。

RubyからMySQLを使いたい時はmysql2というのを使うようです。

参考:RubyでMySQLに繋ぐためのruby-mysqlとmysql2 - tagomorisのメモ置き場


4. database.ymlを作成

プログラムからDBにアクセスする為に、DB情報を書いた設定ファイルを作ります。

各値は、自分の環境に合わせて設定して下さい。

development:

adapter: mysql2
database: hoge
host: localhost
username: root
password: xxxxxx
encoding: utf8


5. Rubyファイルを作成

ようやくコードを書きます。長かった。。

使うのはタイトルにある通りSinatraです。

# coding:utf-8

require 'active_record'
require 'mysql2'
require 'sinatra'

# DB設定ファイルの読み込み
ActiveRecord::Base.configurations = YAML.load_file('database.yml')
ActiveRecord::Base.establish_connection('development')

class Topic < ActiveRecord::Base
end

# 最新トピック10件分を取得
get '/topics.json' do
content_type :json, :charset => 'utf-8'
topics = Topic.order("created_at DESC").limit(10)
topics.to_json(:root => false)
end

# トピック投稿
post '/topic' do
# リクエスト解析
reqData = JSON.parse(request.body.read.to_s)
title = reqData['title']
description = reqData['description']

# データ保存
topic = Topic.new
topic.title = title
topic.description = description
topic.save

# レスポンスコード
status 202
end

基礎的な機能として、


  • 最新トピック10件分を取得する GET /topics.json

  • トピックを登録する POST /topic

を作ってみました。


6. 実行

書いたコードを動かします。ここでもちょっとはまった事があったので注意!(参考:Sinatraがデフォルトでは外部から繋がらなくなってたよ #Sinatra #Ruby - Qiita [キータ]

$ bundle exec ruby hoge.rb -o 0.0.0.0

[2013-05-19 21:37:56] INFO WEBrick 1.3.1
[2013-05-19 21:37:56] INFO ruby 1.9.3 (2013-02-06) [x86_64-linux]
== Sinatra/1.4.2 has taken the stage on 4567 for development with backup from WEBrick
[2013-05-19 21:37:56] INFO WEBrick::HTTPServer#start: pid=10667 port=4567


7. 動作確認


最新のトピックを取得

プログラムを動かしてるサーバの /topics.json にリクエストを送って動作確認をします。仮にlocalhostで動かした場合は、http://localhost:4567/topics.json

GETリクエストを送ると、以下のようなJSON形式のレスポンスが返ってきます。これをベースに変更を加えていけば使えそう。

[

{
"created_at": "2013-05-19T21:29:38+09:00",
"description": "description3",
"id": 3,
"title": "title3",
"updated_at": "2013-05-19T21:29:38+09:00"
},
{
"created_at": "2013-05-19T21:29:29+09:00",
"description": "description2",
"id": 2,
"title": "title2",
"updated_at": "2013-05-19T21:29:29+09:00"
},
{
"created_at": "2013-05-19T21:29:21+09:00",
"description": "description1",
"id": 1,
"title": "title1",
"updated_at": "2013-05-19T21:29:21+09:00"
}
]


トピックの登録

http://localhost:4567/topic に、以下のようなBodyのPOSTリクエストを送ります。すると202レスポンスが返ってきます。

ちなみにPOSTリクエストを送るのは、Chrome拡張機能のDevHTTPClientを使ってます。

{

"title": "title4",
"description": "description4"
}

ちゃんと登録されてるかを、GET /topics.json で確認。

[

{
"created_at": "2013-05-19T21:48:56+09:00",
"description": "description4",
"id": 4,
"title": "title4",
"updated_at": "2013-05-19T21:48:56+09:00"
},
{
"created_at": "2013-05-19T21:29:38+09:00",
"description": "description3",
"id": 3,
"title": "title3",
"updated_at": "2013-05-19T21:29:38+09:00"
},
{
"created_at": "2013-05-19T21:29:29+09:00",
"description": "description2",
"id": 2,
"title": "title2",
"updated_at": "2013-05-19T21:29:29+09:00"
},
{
"created_at": "2013-05-19T21:29:21+09:00",
"description": "description1",
"id": 1,
"title": "title1",
"updated_at": "2013-05-19T21:29:21+09:00"
}
]


おわり

いやーほんとに簡単に書けますね。

あとは、Sinatra と ActiveRecord を勉強しながらちゃんと実装していこうと思います。あと色々自動化していきたいなー。

何か間違ってる所とかありましたらご指摘お願いしますm(_ _)m