何かやってみるブログ

興味をもったこと、趣味のこと、技術について色々書きます。

curlコマンドでAPIサーバーの仕様を確認してみた[Rails]

今回はcurlコマンドを使って、Railsで作成した簡単なブログアプリのAPIサーバーからきちんと想定したjsonが返ってくるのかどうかを試してみます。

環境構築

環境構築をします。データベースにはMySQLでRailsのAPIモードでAPIサーバーをローカルに作成します。

Dockerの環境構築方法は以下の記事にまとめてあります。ただ今回は、APIモードを使いたいと思うのでrails newする時に-- apiオプションを付けたいと思います。

$ docker-compose run web rails new . -f  -d=mysql --api

www.takayasugiyama.com railsguides.jp

サーバーを立ち上げてデータベースを作成すれば環境構築は完了です。

$ docker-compose up -d
$ docker-compose  run web rails db:create

ブログの機能を作成する

モデルを作成する

カラム名 データ型
title string
content text

idcreated_atupdated_atは省略しています。

ブログモデルを上のような形で作成したいと思います。

$ docker-compose run web rails g model Blog title:string content:text
$ docker-compose run web rails db:migrate

schema.rbなどをみてブログのテーブルが作成されていればOKです。

コントローラーを作成する

$ docker-compose run web rails g controller Api::V1::Blogs  create show index destroy update
class Api::V1::BlogsController < ApplicationController
  before_action :set_blog, only: %i[show update destroy]
  before_action :blogs_params, only: %i[create update]
  def create
    @blog = Blog.new(blogs_params)
    if @blog.save
      render json: { data: @blog, status: :created }
    else
      render json: { data: @blog.errors.full_messages, status: :bad_request }
    end
  end

  def show
    render json: { data: @blog, status: :ok }
  end

  def index
    @blogs = Blog.order(created_at: :desc)
    render json: { data: @blogs, status: :ok }
  end

  def destroy
    @blog.destroy
    render json: { data: 'ブログ記事を削除しました', status: :ok }
  end

  def update
    if @blog.update(blogs_params)
      render json: { data: @blog, status: :ok }
    else
      render json: { data: "正常に更新できませんでした", status: :bad_request }
    end
  end

  private

  def blogs_params
    params.require(:blog).permit(:title, :content)
  end

  def set_blog
    @blog = Blog.find_by(id: params[:id])
  end
end

ルーティングの設定をする

Rails.application.routes.draw do
  namespace :api do
    namespace :v1 do
      resources :blogs
    end
  end
end
上のようにルーティングを書いて、ターミナルできちんとルーティングができているか確認します。
$ docker-compose run web rails routes

f:id:s-takaya1027:20200327113324p:plain 上記の画像のようにルーティングができればOKです。

データを作成する

seedで適当にデータを作成します。

10.times do |i|
  Blog.create(title: "title#{i}", content: "content#{i}")
end
$ docker-compose run web rails db:seed

rails consoleでデータを確認できればOKです。

$ docker-compose run web rails c
 irb(main):001:0> Blog.all
   (0.6ms)  SET NAMES utf8mb4,  @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'),  @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483

>, #<Blog id: 3, title: "title2", content: "content2", created_at: "2020-03-27 03:19:11", updated_at: "2020-03-27 03:19:11">, #<Blog id: 4, title: "title3", content: "content3", created_at: "2020-03-27 03:19:11", updated_at: "2020-03-27 03:19:11">, #<Blog id: 5, title: "title4", content: "content4", created_at: "2020-03-27 03:19:11", updated_at: "2020-03-27 03:19:11">, #<Blog id: 6, title: "title5", content: "content5", created_at: "2020-03-27 03:19:11", updated_at: "2020-03-27 03:19:11">, #<Blog id: 7, title: "title6", content: "content6", created_at: "2020-03-27 03:19:11", updated_at: "2020-03-27 03:19:11">, #<Blog id: 8, title: "title7", content: "content7", created_at: "2020-03-27 03:19:11", updated_at: "2020-03-27 03:19:11">, #<Blog id: 9, title: "title8", content: "content8", created_at: "2020-03-27 03:19:11", updated_at: "2020-03-27 03:19:11">, #<Blog id: 10, title: "title9", content: "content9", created_at: "2020-03-27 03:19:11", updated_at: "2020-03-27 03:19:11">]>
irb(main):002:0> exit

curlコマンドで確認する

いい感じでCUIで確認したいので、jqをパイプで渡します。 入っていない場合はインストールが必要です。

Macの場合は、brewでインストールできます。

$ brew install jq

stedolan.github.io

ブログ一覧( http://localhost:3000/api/v1/blogs ) GET

$ curl http://localhost:3000/api/v1/blogs | jq .

{
  "data": [
    {
      "id": 10,
      "title": "title9",
      "content": "content9",
      "created_at": "2020-03-27T03:19:11.618Z",
      "updated_at": "2020-03-27T03:19:11.618Z"
    },
    {
      "id": 9,
      "title": "title8",
      "content": "content8",
      "created_at": "2020-03-27T03:19:11.612Z",
      "updated_at": "2020-03-27T03:19:11.612Z"
    },
    {
      "id": 8,
      "title": "title7",
      "content": "content7",
      "created_at": "2020-03-27T03:19:11.607Z",
      "updated_at": "2020-03-27T03:19:11.607Z"
    },
    {
      "id": 7,
      "title": "title6",
      "content": "content6",
      "created_at": "2020-03-27T03:19:11.601Z",
      "updated_at": "2020-03-27T03:19:11.601Z"
    },
    {
      "id": 6,
      "title": "title5",
      "content": "content5",
      "created_at": "2020-03-27T03:19:11.595Z",
      "updated_at": "2020-03-27T03:19:11.595Z"
    },
    {
      "id": 5,
      "title": "title4",
      "content": "content4",
      "created_at": "2020-03-27T03:19:11.589Z",
      "updated_at": "2020-03-27T03:19:11.589Z"
    },
    {
      "id": 4,
      "title": "title3",
      "content": "content3",
      "created_at": "2020-03-27T03:19:11.583Z",
      "updated_at": "2020-03-27T03:19:11.583Z"
    },
    {
      "id": 3,
      "title": "title2",
      "content": "content2",
      "created_at": "2020-03-27T03:19:11.577Z",
      "updated_at": "2020-03-27T03:19:11.577Z"
    },
    {
      "id": 2,
      "title": "title1",
      "content": "content1",
      "created_at": "2020-03-27T03:19:11.568Z",
      "updated_at": "2020-03-27T03:19:11.568Z"
    },
    {
      "id": 1,
      "title": "title0",
      "content": "content0",
      "created_at": "2020-03-27T03:19:11.560Z",
      "updated_at": "2020-03-27T03:19:11.560Z"
    }
  ],
  "status": "ok"
}

ブログ一覧が確認できました。

ブログ詳細( http://localhost:3000/api/v1/blogs/:id ) GET

試しにid3のブログを取得できるか確認したいと思います。

$ curl  http://localhost:3000/api/v1/blogs/3  | jq 

{
  "data": {
    "id": 3,
    "title": "title2",
    "content": "content2",
    "created_at": "2020-03-27T03:19:11.577Z",
    "updated_at": "2020-03-27T03:19:11.577Z"
  },
  "status": "ok"
}

ブログ作成(http://localhost:3000/api/v1/blogs) POST

試しにtitleが「title10」でcontentが「content10」のブログを作成します。

$ curl http://localhost:3000/api/v1/blogs --request POST --data '{ "title": "title10", "content": "content10" }' --header 'Content-Type: application/json' | jq

{
  "data": {
    "id": 11,
    "title": "title10",
    "content": "content10",
    "created_at": "2020-03-27T04:31:35.483Z",
    "updated_at": "2020-03-27T04:31:35.483Z"
  },
  "status": "created"
}

ブログのデータが作成できました。

ブログ更新(http://localhost:3000/api/v1/blogs/:id) PATCH

先ほど作成したidが11のブログのデータを更新したいと思います。

$ curl http://localhost:3000/api/v1/blogs/11 --request PATCH --data '{ "title": "title10 edited", "content": "content10 edited" }' --header 'Content-Type: application/json' | jq


{
  "data": {
    "id": 11,
    "title": "title10 edited",
    "content": "content10 edited",
    "created_at": "2020-03-27T04:31:35.483Z",
    "updated_at": "2020-03-27T04:35:55.413Z"
  },
  "status": "ok"
}

無事にデータが更新されました。

ブログ削除(http://localhost:3000/api/v1/blogs/:id) DELETE

先ほど更新したidが11のブログを削除したいと思います。

$ curl http://localhost:3000/api/v1/blogs/11 --request DELETE  --header 'Content-Type: application/json' | jq

{
  "data": "ブログ記事を削除しました",
  "status": "ok"
}

$ curl http://localhost:3000/api/v1/blogs/11 | jq

{
  "data": null,
  "status": "ok"
}

最初のコマンドでデータを削除し、あとのコマンドでデータが削除されたことを確認しました。

以上でRailsをDockerで環境構築してcurlコマンドでAPIサーバーの仕様が確認できました。