【Rails API】HTTPメソッドで困ったことを振り返ってみる【Postman】

こんにちは。あがさんです！！

今回はAPIについて投稿です。
Railsで作ったプロジェクトをAPIとしても利用できるようにする設定や注意点をお伝えできればと思います。
宜しくお願います。

## APIとは
アプリケーションやサービス同士が互いにデータをやり取りし、機能を利用するためのインターフェースやプロトコルのことです。簡単に言うと、**便利機能を外部向けに提供するための仕組みです。**

## RailsプロジェクトをAPI化する
自分で作っいたRubyonRailsプロジェクトをAPI向けに改修しました。
API化することでRailsプロジェクトの外部からデータのやり取りが可能になります。
今回はPostmanを使ってRailsAPIと連携するための方法を説明します。

ポイントは以下の4つです。
- gem 'rack-cors'をbundleインストール
- routes.rb
- api/v1/articles_controller.rb
- cors.rb

## gem 'rack-cors'と CORS
rack-corsは、RailsアプリケーションでCORS（Cross-Origin Resource Sharing）を設定するためのGemです。設定することで外部のドメインからのHTTPリクエストが許可され、他のウェブアプリケーションやクライアントからRailsのAPIにアクセスできるようになります。

``` 
# Gemfile
gem 'rack-cors'
```

``` 
# bash
bundle install
```
### cors.rb
bundle installの後にcors.rbを作成して下記のように記述します。
```cors.rb
# config/initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins '*'
    resource '*', headers: :any, methods: [:get, :post, :put, :patch, :delete, :options, :head]
  end
end

```
※ `origins '*'`という箇所はすべての外部ドメインからのアクセスを許可しているという意味になります。特定のドメインからだけリクエストを受けたい場合は変更が必要です。

### その他改修したコード
### routes.rb
API用のルーティングを既存のルーティングとは別に追記しました。
従来のRailsプロジェクトで`http://localhost:3000/articles/`にアクセスすれば、indexアクションのページでデータを取得できましたが、**APIからindexアクションのデータを取得するためには`http://localhost:3000/api/v1/articles/`というURLからアクセスする必要があります。**
```routes.rb
Rails.application.routes.draw do
  namespace :api do
    namespace :v1 do
      resources :articles, only: [:index, :show, :create, :update, :destroy]
    end
  end
end
```

### api/v1/articles_controller.rb
既存の `app/controllers/articles_controller.rb`とは別にAPIの用のコントローラーの作成が必要です。
ポイントは.erbファイルに表示させるのではく、外部ドメインにそれぞれのアクションごとにJSONの情報を返すために`render json: @articles`という記述をします。
```articles_controller.rb
# app/controllers/api/v1/articles_controller.rb
module Api
  module V1
    class ArticlesController < ApplicationController
      # GET /articles
      def index
        @articles = Article.all
        render json: @articles
      end

      # GET /articles/:id
      def show
        @article = Article.find(params[:id])
        render json: @article
      end

      # POST /articles
      def create
        @article = Article.new(article_params)
        if @article.save
          render json: @article, status: :created
        else
          render json: @article.errors, status: :unprocessable_entity
        end
      end

      # PUT /articles/:id
      def update
        @article = Article.find(params[:id])
        if @article.update(article_params)
          render json: @article
        else
          render json: @article.errors, status: :unprocessable_entity
        end
      end

      # DELETE /articles/:id
      def destroy
        @article = Article.find(params[:id])
        @article.destroy
        head :no_content
      end

      private

      def article_params
        params.require(:article).permit(:title, :subtitle, :body, :tag, :user_id)
      end
    end
  end
end
```


## Postmanを使ってHTTPリクエスト
Rails側のサーバーを起動して、外部からデータのやり取りが可能かテストしました。
今回は[Postman](https://www.postman.com)を使って確認します。

#### 今回利用するHTTPメソッドとURL
| メソッド | URL | 備考|
| ---- | ---- | ---- |
| GET |http://localhost:3000/api/v1/articles/ | 一覧画面や詳細画面でデータ取得 |
| POST | http://localhost:3000/api/v1/articles/| データを新規作成|
| PUT |http://localhost:3000/api/v1/articles/.:id | データを更新 |
| DELET | http://localhost:3000/api/v1/articles/2| データを削除 |

### 【実施した操作】

1. POSTメソッドを使い、`"id": 19`のデータを新規作成。
![POST](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3775546/87ac455c-c24f-b7c6-e51e-996469647935.png)

2. GETメソッドを使い、`"id": 19`含めたすべてのデータを取得。
![GET](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3775546/9445bda4-3404-0b71-f05a-17a4bff4d819.png)

3. PUTメソッドを使い、`"id": 19`のデータを更新。
![POST](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3775546/74ffc837-f6b2-b742-b950-b3fd2f032503.png)

4. DELETEメソッドを使い、`"id": 18`のデータを削除。
![DELETE](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3775546/2c7d2652-08b5-618a-e852-1a114878d19a.png)

5. 改めてGETメソッドを使いすべてのデータを取得。`"id": 18`のデータが削除され、`"id": 19`のデータが更新されていることを確認。
![GET](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3775546/d7ac8fae-80b9-4452-7a3e-8b0ea8afe40e.png)


無事にPostmanと連携ができており、APIとして機能していることが確認できました。

## まとめ
いかがでしたでしょうか。
実はAPIとかHTTPメソッドとかプログラミング始めたての時に少し触れてみたんですけど、処理の流れやデータのやり取りがわかりづらくて苦手だったんですよね、、、。

今回は取り組む際は自分で作ったアプリを改修するところから徐々に移行できたので、
ルーティングやデータの扱いなど把握しながら進められました。

CORS設定やControllerの記述で少し沼ってしまいましたが最終的に動作できるようになって安心しました。
Postmanで201 Createdとか返事がもらえるとちょっぴり嬉しいですね！

また次回も頑張って投稿します。
最後まで見ていただきありがとうございました!!

*~Qiitaの歴史がまた1ページ~*


関連リンク：

- [Postman](https://www.postman.com)