Nuxt.js × Rails APIモードでアプリケーションを作る

## やりたいこと
Nuxt.jsでフロントを、RailsでAPIを作る
作成したAPIに対してPostmanで投稿をする
※ [次の記事](https://qiita.com/rearail/items/561fab1a15858c9f2e31)でNuxt.js側からRailsのAPIを叩いてDBにデータを保存する方法を掲載します

> **開発環境**
ruby 2.6.5
Rails 6.0.3.4
node v14.7.0
yarn 1.22.4


### フロントをNuxt.jsで作る
- post-appというディレクトリの中に`app`という名前でフロント用のアプリケーションを作る
- Axiosはプロジェクト作成時にインストールするように選択する

```
// post-appというディレクトリを作る
$ mkdir post-app
$ cd post-app

// nuxtでのアプリケーションを作る
$ npx create-nuxt-app app

// 各種設定を選択する
? Project name: (app)
└ そのままEnterボタン押す

? Programming language: (Use arrow keys)
❯ JavaScript
  TypeScript
└ JavaScriptを選択

? Package manager:
❯ Yarn
  Npm
└ Yarnを選択

? UI framework: (Use arrow keys)
❯ None
  Ant Design Vue
  Bootstrap Vue
  Buefy
  Bulma
  Chakra UI
  Element
  Framevuerk
  iView
  Tachyons
  Tailwind CSS
  Vuesax
  Vuetify.js
└ Noneを選択

? Nuxt.js modules:
❯◉ Axios
 ◯ Progressive Web App (PWA)
 ◯ Content
└ Axiosを選択（スペースキーを押す）

? Linting tools: (Press <space> to select, <a> to toggle all, <i> to invert selection)
❯◯ ESLint
 ◯ Prettier
 ◯ Lint staged files
 ◯ StyleLint
└ そのままEnterボタン押す

? Testing framework: (Use arrow keys)
❯ None
  Jest
  AVA
  WebdriverIO
└ そのままEnterボタン押す

? Rendering mode:
  Universal (SSR / SSG)
❯ Single Page App
└ Single Page Appを選択

? Deployment target: (Use arrow keys)
❯ Server (Node.js hosting)
  Static (Static/JAMStack hosting)
└ Serverを選択

? Development tools:
❯◉ jsconfig.json (Recommended for VS Code if you're not using typescript)
 ◯ Semantic Pull Requests
└ jsconfig.jsonを選択（スペースキーを押す）
```

### nuxtのポート番号を8000番に変更する
[公式ページ](https://ja.nuxtjs.org/faq/host-port/)

公式より引用▼

```js:app/nuxt.config.js
export default {
  server: {
    port: 8000, // デフォルト: 3000
    host: '0.0.0.0' // デフォルト: localhost
  }
  // その他の設定
}
```

**実際の記述▼**

```js:app/nuxt.config.js
server: {
  port: 8000,
},
```

### ローカルホストを立ち上げる
```
$ cd app
$ yarn dev

// 下記が表示されたらhttp://localhost:8000/でアクセス可能

   │   Nuxt.js @ v2.14.7                   │
   │                                       │
   │   ▸ Environment: development          │
   │   ▸ Rendering:   client-side          │
   │   ▸ Target:      server               │
   │                                       │
   │   Listening: http://localhost:8000/
```

### RailsでAPIサーバーを作る
```
// APIモード、DBはMySQLでrailsアプリケーションを作る
$ rails new api --api -d mysql

// DBを作る
$ rails db:create
Created database 'api_development'
Created database 'api_test'
```

### ModelとControllerを作る
```
// Post Modelを作る
$ rails g model Post title:string body:text

// migrateする
$ rails db:migrate

// apiディレクトリの中のv1ディレクトリの中にpostsコントローラーを作る
// test用のディレクトリの自動生成をスキップする 
$ rails g controller api::v1::posts --skip-test-framework
```

### ルーティングの設定
- `/api/v1/posts`というルーティングを作る

```ruby:api/config/routes.rb
Rails.application.routes.draw do
  namespace :api do
    namespace :v1 do
      resources :posts
    end
  end
end
```

### PostsControllerを設定する
```ruby:api/app/controllers/api/v1/posts_controller.rb
class Api::V1::PostsController < ApplicationController
  before_action :set_post, only: [:show, :update, :destroy]

  def index
    posts = Post.order(created_at: :desc)
    render json: { status: 'SUCCESS', message: 'Loaded posts', data: posts }
  end

  def show
    render json: { status: 'SUCCESS', message: 'Loaded the post', data: @post }
  end

  def create
    post = Post.new(post_params)
    if post.save
      render json: { status: 'SUCCESS', data: post }
    else
      render json: { status: 'ERROR', data: post.errors }
    end
  end

  def destroy
    @post.destroy
    render json: { status: 'SUCCESS', message: 'Deleted the post', data: @post }
  end

  def update
    if @post.update(post_params)
      render json: { status: 'SUCCESS', message: 'Updated the post', data: @post }
    else
      render json: { status: 'SUCCESS', message: 'Not updated', data: @post.errors }
    end
  end

  private

  def set_post
    @post = Post.find(params[:id])
  end

  def post_params
    params.permit(:title, :body)
  end
end
```

### Postmanを使って投稿してみる
[Postman](https://www.postman.com/)
[使い方参考記事](https://meetup-jp.toast.com/818)
- 下記のようになっていたらOK
![Postman.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657259/ca4f2fb3-504e-5ae3-a929-1647926a96da.gif)

### Railsのコンソールで投稿できている確認する
```
// コンソールを立ち上げる
$ rails c

// 投稿を確認する
irb(main):001:0> Post.first
```
上記でPostmanと同じ内容が表示されていればOKです

*※別の記事でNuxt.js側からデータを投稿する処理を実装します*