SinatraでJSONを返却する簡易APIを作成してherokuにプッシュして使うまでをまとめてみました

SinatraでJSONを返却する簡易APIを作成してherokuにプッシュして使うまでをまとめてみましたもともとアプリ開発用に簡単なAPIを作りたいなと思ってここ数日Sinatraなどをいじっていました。その成果をまとめてみたいと思います。ぜんぜん、簡易じゃなかったです。herokuまでやらなければほんとに簡易なんですけどね。あと、はっきり言ってダサいコードなんですが、まぁ(><)

必要なもの

事前にお伝えしたいこと

  • sample-sinatra-apiはherokuに登録したアプリ名です。適宜ご自身のアプリ名に読み替えて下さい。
  • もっと良い方法がたくさんあると思います。あと、数日前にHerokuやSinatraに触った初心者が書いたフローなので無駄や変なことやかっこわるいことが多いと思います。

作成手順

必要なgemをインストールする

$ Bundle init

中身はこんな感じ。

source "https://rubygems.org"
ruby '2.0.0'

gem "sinatra"
gem "sinatra-contrib"
gem "sinatra-activerecord", :require => 'sinatra/activerecord'
gem "activerecord"
gem "rake"

group :development do
  gem 'sqlite3'
end

group :production do
  gem 'pg'
  gem "activerecord-postgresql-adapter"
end

bundleをインストールする

$ bundle install --path vendor/bundle

Rakefileを作成する

$ touch Rakefile

中身はこんな感じ。

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

データベースの設定を作成します。

database.ymlを作成します。

$ mkdir config
$ touch config/database.yml

中身はこんな感じです。herokuの情報というところは後ほど設定します。

development:
  adapter: sqlite3
  database: development.db

test:
  adapter: sqlite3
  database: test.db

production:
  adapter: postgresql
  host: [herokuの情報]
  port: [herokuの情報]
  database: [herokuの情報]
  username: [herokuの情報]
  password: [herokuの情報]

migrationファイルを作成する

create_countriesのcountriesの部分がテーブル名になります。今回はcountriesのテーブルを作ってみました。

$ bundle exec rake db:create_migration NAME=create_countries

プロジェクトディレクトリを見ると、db/migrateディレクトが生成されていて、その中に、20140321174420_create_countries.rbというファイルがあります。これを編集します。

class CreateCountries < ActiveRecord::Migration
  def change
    create_table :countries do |t|
      t.string :name
      t.string :color
    end
  end
end

こんな感じにしました。シンプルです。とりあえず、国名と色(2カラム欲しかっただけですが汗)のカラムを持ったテーブルを作ります。そして、マイグレーションしてテーブルを作成します。

$ bundle exec rake db:migrate

成功すると、dbディレクトリ下にschema.rbというファイルが生成されます。また、development.dbというファイルがルートにできています。

アプリのファイルを作成する。

APIを記述するところです。

$ touch app.rb

中身はこんな感じです。

require "sinatra"
require "sinatra/reloader"
require "active_record"
require "sinatra/json"

ActiveRecord::Base.establish_connection(ENV['DATABASE_URL'] || 'sqlite3://localhost/development.db')

class Country < ActiveRecord::Base
end

get '/' do
  "simple-sinatra-api"
end

get '/countries' do
  @countries = Country.order("id asc").to_a
  countries = Array.new()
  @countries.each do |country|
    countries.push({id: country.id, name: country.name, color: country.color})
  end
  output = {countries: countries}
  json output
end

ActiveRecord::Base.establish_connection(ENV['DATABASE_URL'] || 'sqlite3://localhost/development.db')の意味は、通常なら手元のdevelopment.dbを使う。herokuの時にはherokuのDBを使うというような感じです。

とりあえずローカル環境で動かす

さて、ここまで出来たら一度ローカル環境では動かしてみます。その前に、csvからマスターデータを挿入してみます。カラムの形に合わせてこんなものを用意してみました。

0,Japan,red
1,US,blue
2,Britain,yellow
3,France,purple
4,Germany,green
5,China,orange
6,India,brown

インポートします。

$ sqlite3 development.db
sqlite> .separator ,
sqlite> .import countries.csv countries
sqlite> select * from countries;
0,Japan,red
1,US,blue
2,Britain,yellow
3,France,purple
4,Germany,green
5,China,orange
6,India,brown
$ruby app.rb

ブラウザにlocalhost:4567と入力します。成功したら、/の場合はsample-sinatra-apiと、/countriesの場合は、JSON形式で先ほどインポートしたcsvが表示されます。

herokuで表示するための準備

最初にgitを用意しておきます。ついでに、.gitignoreを作成してvendorをgit管理対象外にします。herokuがherokuの環境でGemfileからgemをインストールするのでvendor以下のファイルは不要ということなのだと思います。ちなみに残しておくとpushの際にWARNINGが表示されます。

$ git init
$ touch .gitignore
$ git rm -r vendor
$ git add .

.gitignoreの中身はこうなります。

vendor

さて、herokuにアップするための準備を続けます。次に、Procfileを作成します。

$ touch Procfile

中身はこんな感じです。

web: bundle exec ruby app.rb -p $PORT

今度は、

$foreman start

でブラウザに表示してみます。今度はlocalhost:5000をブラウザで表示します。先ほどと同じように//countriesを確認します。OK!

次にherokuにloginします。EmailとPasswordが聞かれるので入力します。

$ heroku login

herokuにアプリを登録します。このコマンドを入力すると、gitのremoteが追加されます。

$ heroku apps:create sample-sinatra-api
$ git remote -v

今回はheroku上でpostgreSQLを利用しますので、その設定をします。

$ heroku addons:add heroku-postgresql --app sample-sinatra-api

Herokuにアクセスすると新しいアプリが追加されています。クリックして、Add-onsPostgresの項目があるのでクリックします。

設定が出てきました。この設定を、database.ymlにコピペしていきます。

次に、データベースURLを環境変数に設定します。

heroku config

とやると、DATABASE_URLと他に幾つか、HEROKU_POSTGRESQL_<色名>_URLというものが出てきます。この色名のついたものを以下のようにセットします。

$ heroku pg:promote HEROKU_POSTGRESQL_AMBER_URL

これで、app.rbに記載したDATABASE_URLに値が入るようになります。

herokuで動かす

gitをプッシュしてみます。

$ git add .
$ git commit -m "first commit"
$ git push heroku master

成功すると、URLが表示されます。http://sample-sinatra-api.herokuapp.com/こんな感じになります。動作を確認します。この状態だと、herokuのdatabaseが設定されていないので、/countriesにアクセスすると、Internal Errorが表示されます。

次に、heroku側のpostgreSQLの設定をします。まずデータベースを作成します。

$ heroku run rake db:migrate

この状態だと空のJSONが出力されてしまうので、用意していたCSVをセットします。既にheroku側にそのCSVもあるので、herokuのpostgreSQLにアクセスして設定してきます。

$ heroku pg:psql
=> \copy countries from 'countries.csv' CSV;
=> \quit

これでhttp://sample-sinatra-api.herokuapp.com/countriesにアクセスすると既定値のJSONが出力されました。やりたいことが一応出来ました。

ここから

ここからapp.rbのapiをいろいろいじってAPIを追加して行ったり、初期データ追加したりして遊べると思います。

あ、あと最終的にはRailsでgrapeを使って構築したいなと思っています。こちらを先にやったほうが良かったのかもしれませんが。ただ、Railsは自分的にはブラックボックスなので最初はSinatraを選択しました。

便利そうなもの

データベースのリセット

$ heroku pg:reset DATABASE

参考リンク

下調べの経緯

Pocket
LINEで送る

You may also like...