最速でAPIをつくろう
写真のフランク・シナトラとは関係ないよ(たぶん)
Androidアプリを書いていて、最初はAPIいらないかと持っていたのですが、今後の実装を考えていくうちにどう考えても辛さしかないわって感じになったので速攻で作りました。
個人的にはAWSのAPI Gatewayとか試したかったんですけど、今回はあまり時間がなかったので。。
(というか日程的にバックエンド開発に時間を割けないorz)
よって一番慣れているもので作りましたとさ
実際にはクローラーが稼働していて、そいつらが読み取ったデーターがMySQLにたまっている感じを想像していただけるとわかると思います。まあ今流行りのクローラーです
とりあえずgem
を入れましょう
gem install sinatra
次にサクッとコードを書きます
例えばDBのテーブルがこんなかんじだったとしまして
create table `hogehoge_items` ( `id` int(10) unsigned not null, `hoge_id` int(10) unsigned not null, `title` varchar(255) not null, `link` varchar(768) not null, `published` varchar(255) not null, `updated` varchar(255) not null, `content` varchar(255) not null, primary key(`id`) ) engine=InnoDB default charset=utf8;
シンタックスハイライトすんじゃん!!びっくり!!
取り乱しました。すみません。出来ないものだとばかり思い込んでいたので。。。
DBスキーマそのまま貼っつけましたが皆さんわかると思うのでこのまま行きます
次に肝心のコードです
require 'active_record' require 'sinatra' db_config = YAML.load_file(File.expand_path(File.join(__FILE__, 'config', 'database.yml'))) ActiveRecord::Base.establish_connection(db_config['db']['production']) set :root, File.expand_path(File.join(__FILE__, '..', 'static')) get '/' do erb :index end get '/news/:hoge_id' do content_type :json, :charset => 'utf-8' entries = GoogleAlertItems.where(hoge_id: params[:hoge_id]).order('updated DESC').limit(10) entries.to_json(:root => false) end
本当をいうと今回実装したのと全然構造違うのですが、説明用に変えて書いています。 とりあえず上から説明していきます
require 'active_record' require 'sinatra'
大丈夫ですね。普通にimport
や#include
といった他の言語にもよくあるライブラリの読み込みです
db_config = YAML.load_file(File.expand_path(File.join(__FILE__, 'config', 'database.yml'))) ActiveRecord::Base.establish_connection(db_config['db']['production'])
ActiveRecordを単体で叩けるように設定を読み込んでいます。db_config['db']['production']
部分をproduction
からdevelopment
変えたりすることで開発環境と本番環境を分けたりなど、色々と便利なのですが、とりあえず今回はそこまで凝ったことしなくていいので
あ。ここでdatabase.yml
は既に存在していること前提で話しています(笑)
set :root, File.expand_path(File.join(__FILE__, '..', 'static'))
Sinatraは静的ファイルのディレクトリの場所を変更することが可能です。今回は色々な関係でstaticというフォルダを指定しています
get '/' do erb :index end get '/news/:hoge_id' do content_type :json, :charset => 'utf-8' entries = GoogleAlertItems.where(hoge_id: params[:hoge_id]).order('updated DESC').limit(10) entries.to_json(:root => false) end
メインディッシュですね。Sinatraの特徴はMVCアーキテクチャーに則っていないことです。乱暴に言うとCしか持っていません。そしてこれはルーティングを書いているだけです。
ちゃんと設計してあげれば立派なMVCフレームワークになるのですが、ならRails使えよって話で(笑)
ちなみにSinatraをベースにMVCアーキテクチャーを持たせた設計にしてあるのがPadrinoってやつです
僕はいまいちRailsに比べての優位な部分を見いだせていないので使ったことないです。すません
get '/' do erb :index end
これはサイトのトップディレクトリに来たらstatics
フォルダーにあるindex.erb
をrender
する処理を書いています。ちなみにhaml
だろうがslim
だろうが適切なgem
を入れてあげれば対応できます
get '/news/:hoge_id' do content_type :json, :charset => 'utf-8' entries = GoogleAlertItems.where(hoge_id: params[:hoge_id]).order('updated DESC').limit(10) entries.to_json(:root => false) end
これはなんかややこしそうですね。しかし分解して読み解けば簡単です
get '/news/:hoge_id' do
でURLに含まれている/news/
以下の文字列を読み取ります。よって
/news/yoshio
というURLに対してアクセスが来た場合、
yoshio
という文字列がsinatra側に渡されることになります
GoogleAlertItems.where(hoge_id: params[:hoge_id]).order('updated DESC').limit(10)
ここで何をしているかというと、URLから読み取った文字列をActiveRecordに渡して、hoge_id
と一致するものを持ってきて更に更新日時が新しい順にし、そして最大10件持ってくるという処理をしています
entries.to_json(:root => false)
説明不要かもですが、みんなだいすきJSONを生成しています。最終的にこいつが結果としてrender
されます
今回はget
しか使っていませんが、もちろんpost
もupdate
もdestroy
も可能です。
長くなったのでここで終わりにしますが、次回はunicornでデーモン化した話を書きたいです
(ちゃんと次回があればの話だがなっ!)
あ。。。GPUの連載止めてた。。書きます