スクリプトのお勉強 技術

Ruby(Rails)で最小限にREST APIを立ち上げる

投稿日:

簡単に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

-スクリプトのお勉強, 技術

執筆者:

関連記事

小ネタ: Python のdataclass でNone or “”を使わないJSONデータを定義する

PythonをREST APIのクライアントとして作成する際、dataclassesを使用しようと思いました。型が見た瞬間分かるし、しっかりしているからです。 でも、そのREST API は&#822 …

poetry installでJSONDecodeError

小ネタです。OSをアップデートしたので、その他もいろいろアップデートしようとしたらエラーになったので、メモとして書いておきます。 WSL2のUbuntuを 22.04 LTSにアップデート は、さほど …

「Python3 メモ」 独自例外クラスからの値取得/変数の内容取得

忙しい。。 この時期でなぜか忙しく、ブログ書いてる暇ない。。のでメモ書き程度。そして、内容をよく忘れるやつ。。 python3の独自例外クラス 例外クラスからの値取得方法をいつも忘れます。ある関数or …

unconstant – perlライブラリ

ちょっとだけperlの機能修正をしたので、そのときに使用したライブラリについて書こうと思います。 perlのunconstant です。 use constantの解除 use constantとは固 …

PythonでPKCS#12を使用して暗号/復号する

1. はじめに 仕事でVPN関係のシステム開発をすることになりました。まずは暗号機能の基本を思い出すため、Pythonで、PKCS#12の公開鍵で暗号、秘密鍵で復号するプログラムを作ってみようと思いま …

google オプトアウト Click here to opt-out.