railsのapiを使ってみる

#はじめに
railsでapiを作るにはrails new appname --apiみたいにするのは知っていたけど具体的なapiの作り方がわからなかったから調べながら作ってみた。

#作るもの
とりあえず作るものとしてはユーザーのデータを送ったり送られたデータをもとにユーザーを作成、編集するもの。


#api用アプリとapiを使うアプリを作る

まずapi用とそれを使うアプリを作る。

```
rails new api_user --api
rails new get_api_data_user 
```

みたいにつくる。

まずapiから

#api作成

モデルとコントローラーを作る

```ruby 
rails g model user name:string age:integer email:string password:string 
rails db:migrate
rails g controller users index show create update
```

これでok

コントローラーに具体的な処理を書いていく


基本的にapiの場合はjson形式で値をやり取りするっぽい？

なのでviewsは使わず render json:

みたいにjsonの値を出力していく

それでこんな感じ

```ruby:users_controller.rb
class UsersController < ApplicationController
  def index
    @users = User.all 
    render json: @users 
  end

  def show
    @user = User.find params[:id]
    render json: @user 
  end

  def update
    @user = User.find params[:id]
    @user.update(user_params)
  end

  def create
    @user = User.new(user_params)

    @user.save
  end

  private 

  def user_params 
    params.require(:user).permit(:name,:age,:email,:password)
  end 
end
```

最後にrender json:がついただけで普通:relaxed:

routesに

```
resources :users
```

とかいておわり。


#apiを使う側のアプリを作成

apiにデータを送る場合にcurlというコマンドを使う

```ruby
curl -X GET http://localhost:3000/users
```

と書いたらlocalhost:3000で動いているapiの/usersにアクセスしてデータをもらってくる

でもそのデータをそのままは使わず

```ruby 
JSON.parse(@users)
```

みたいにjson形式にする。

こうしなかったら配列として扱えなかった。

なのでusers_controller.rbのindexはこうなる。

```ruby
  def index
    @users = `curl -X GET http://localhost:3000/users`
    @users = JSON.parse(@users)
  end
```

ちなみに``でコンソールにコマンドをうつことができる。

これで@usersにさっきのapiからusersのデータをjson形式で持ってこられるのでusers/index.html.erbに

```erb:index.html.erb
<% @users.each do |user| %>
    <p>name</p>
    <p><%= user["name"] %></p>
    <p>age</p>
    <p><%= user["age"] %></p>
    <p>email</p>
    <p><%= user["email"] %></p>
    <p>password</p>
    <p><%= user["password"] %></p>
<% end %>
```

でデータをみることができる。

あくまでhashの形なのでuser["name"]としないとデータはとれない。


create updateに関してコントローラーはこんな感じ

```ruby
  def new 
  end 

  def create 
    `curl -X POST -H 'Content-Type:application/json' -d '{ "name": "#{params[:name]}", "age": "#{params[:age]}", "email": "#{params[:email]}", "password": "#{params[:password]}"}' http://localhost:3000/users`
    redirect_to users_index_path
  end 

  def edit 
  end 

  def update 
    p `curl -X PATCH -H 'Content-Type:application/json' -d '{ "name": "#{params[:name]}", "age": "#{params[:age]}", "email": "#{params[:email]}", "password": "#{params[:password]}"}' http://localhost:3000/users/#{params[:user_id]}`
  end 
```

さっきと違うのは-H 'Content-Type:application/json'みたいしているところ

こう書かないとうまくデータをapiに渡せない


それで全体はこうなる。

```ruby:users_controller.rb
class UsersController < ApplicationController
  def index
    @users = `curl -X GET http://localhost:3000/users`
    @users = JSON.parse(@users)
  end

  def new 
  end 

  def create 
    `curl -X POST -H 'Content-Type:application/json' -d '{ "name": "#{params[:name]}", "age": "#{params[:age]}", "email": "#{params[:email]}", "password": "#{params[:password]}"}' http://localhost:3000/users`
    redirect_to users_index_path
  end 

  def edit 
  end 

  def update 
    p `curl -X PATCH -H 'Content-Type:application/json' -d '{ "name": "#{params[:name]}", "age": "#{params[:age]}", "email": "#{params[:email]}", "password": "#{params[:password]}"}' http://localhost:3000/users/#{params[:user_id]}`
  end 

  def show
  end
end
```

#おわりに

アイディアが思い浮かばなかったから変なものができてしまった。

ちなみにapiを試すためにローカルで二つのサーバーを起動したい場合は

rails s -p 4000

みたいにすればlocalhost:4000にアクセスできる:sunny:

ちなみにユーザ登録とか検索とか画面を表示する以外の部分をほかのapiにやらせるのってありなのかな....？

なんかデータを処理するのと表示するのをはっきり分けられてよさそう:eyes:

おわり