簡単にREST APIを立ち上げたいなーと思うときが仕事であります。
別にRubyでなくてもいいのですが、一応前提がRubyであることにします。
仕事で必要になるには
現在の仕事を鑑みると、最低限以下のサンプルを作成したい思います。
- Rails APIモード(最小限)
- テスト(Rspec)
- カバレージ
- 循環的複雑度検査
あと、私の趣味でRedisを使用します。
本記事ではAPIとテスト(簡易版)とRedis
上記の通り、テストは欲しいんですが、本記事では以下だけ行います。
- Rails API(最小限)
- Redis model
- cacheではなくmodelとして定義
- あえてActiveModelは使わない
- テスト(Rspec)
- とりあえずコードを呼び出すだけ
動作環境
使用した環境は以下です。
- WSL2 (Windows 11)
- ubuntu 24.04 LTS
- Ruby 3.2.3
- Rails 7.2.0
- Redis 7.2.4
- Dockerで起動
Rails APIモード
以下のように”rapi”というアプリケーションを作ります。
$ bundle config set path 'vendor/bundle' $ bundle install $ bundle exec rails new rapi --skip-action-mailer \ --skip-action-mailbox \ --skip-action-text \ --skip-active-job \ --skip-active-storage \ --skip-action-cable \ --skip-asset-pipeline \ --skip-javascript \ --skip-hotwire \ --skip-jbuilder \ --skip_ci \ --devcontainer \ --api $ cd rapi $ vi Gemfile gem "redis-client"
新規アプリケーションのときは、”rapi”を検索して、それぞれ変更していけばいいことになります。
Redis
RedisをActiveModelとして使用しない
あえてRedis用のActiveModelを使用しませんでした。
Redis::Ojbect等を使えば作れるでしょうけど、まずは素Modelクラスとして使用します。
ソース
ここのような実装をしてみました。
住所録 APIをつくってみた
サンプルとしてRedisに住所を登録するAPIを作成してみました。
RSpec準備
まずはRSpecを導入しておきます。ついでにAPIもテスト雛形を作ります。
$ bundle exec rails g rspec:install $ bundle exec rails g rspec:request addrs_api
実装内容
idのprefixに”aid:”というのをつけてみました。特に理由はなかったのですが、意外と面倒でした。。素直にidとして数値にしておいたほうが良かったかもしれないです。
ただ、それだとキーが数値になるので扱いにくいかなと思いました。まぁ一長一短でしょう。
Redis
Docker composeで起動するようにdocker-compose.ymlを記述します。
Redis 接続先
以下がredisの接続先実装です。REDIS_URL環境変数から取り出します。
rails_api_example/rapi$ cat config/initializers/redis.rb ... redis_config = RedisClient.config(url: (ENV['REDIS_URL']).to_s) RedisObj = redis_config.new_pool(timeout: 2.0, size: Integer(ENV.fetch('RAILS_MAX_THREADS', 5))) ...
起動方法
redisも含めて以下のように起動します。
### $ docker-compose up redis ### 別コンソールにて起動 $ cd rapi $ bundle config set path vendor/bundle $ bundle install $ export REDIS_URL=redis://localhost:6379/0 $ bundle exec rails s
ブラウザから
RSpec
単体テストは以下のようにしています。
rails_api_example/rapi$ export REDIS_URL=redis://localhost:6379/0 rails_api_example/rapi$ bundle exec rspec ... Finished in 0.09545 seconds (files took 5.86 seconds to load) 3 examples, 0 failures
動作確認
実際に起動した場合の動作確認を以下のようにしています。
### 作成 $ curl -X POST -H "Content-Type: application/json" -d '{"addr": {"name": "日本 太郎", "birthday": "1990-01-01", "gender": "男性", "address": "北海道", "job": "Engineer", "note": "Sample note"}}' http://localhost:3000/addrs ### 取得(全部) $ curl http://localhost:3000/addrs ### 位置指定 取得 $ curl -X GET http://localhost:3000/addrs/aid:1 {"name":"日本 太郎","birthday":"1990-01-01","gender":"男性","address":"北海道","job":"Engineer","note":"Sample note","aid":"aid:1"} ### 削除 $ curl -X DELETE http://localhost:3000/addrs/aid:1
終わりに
むしろaid:とか変な仕様を作ったので意外と手間がかかりました。仕様大事。。
参考
https://railsguides.jp/api_app.html
https://qiita.com/sho-19202325/items/57da8b494d0dd188e3b5
https://zenn.dev/kei1232/articles/941b465240bc1d
https://nishinatoshiharu.com/usage-redis-objects/
https://zenn.dev/tandems/articles/15e3d2097a4e79