【API初心者向けハンズオン】StrapiでAPI作ってAPI叩くマン

APIってなんなんすか！？
APIを作ってみたい！
APIって作るのむずかしいんでしょ？
エーピーアイ！エーピーアイ！

ダイジョーブキミニモツクレルヨ

# 速攻でAPIが作れるStrapi
StrapiというHeadless Cmsとかってのを使うとコード書かなくてもAPIが作れるんす。

[Strapi公式](https://strapi.io/)

## 用意しておくこと
docker-composeが使えるようにしておくこと
dockerやdocker-composeがよくわからなくてもいいです

[docker](https://www.docker.com/products/docker-desktop)

## 環境構築
docker-compose.ymlで作りますよっと
適当なところでstrapiみたいな適当な名前のフォルダ作って、その中に下記のコードのdocker-compose.ymlを入れます。

```yml:strapi/docker-compose.yml
version: '3'
services:
  strapi:
    container_name: strapi
    image: node:13.3.0
    environment:
      - DATABASE_CLIENT=postgres
      - DATABASE_HOST=db
      - DATABASE_PORT=5432
      - DATABASE_NAME=strapi
      - DATABASE_USERNAME=strapi
      - DATABASE_PASSWORD=strapi
    ports:
      - 1337:1337
    volumes:
      - ./app:/srv/app
    working_dir: /srv/app
    tty: true
    depends_on:
      - postgres
  postgres:
    container_name: postgres
    image: postgres
    restart: always
    volumes:
      - ./db:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: strapi
      POSTGRES_PASSWORD: strapi
      POSTGRES_DB: strapi
```
作ったらターミナルでdocker-compose.ymlと同階層に移動して、

```
$ docker-compose up -d
```
環境構築してくれます。
※ `-d`オプション付けるとバックグラウンドでコンテナ起動します。

## Strapiを作成
次にstrapiという名前のコンテナにはいりますよって

```
$ docker-compose exec strapi /bin/bash
```

コンテナに入ったらStrapiを作成するコマンドを実行します。

```
$ npx create-strapi-app strapi-dev
```
※strapi-devがアプリ名になります。名前はなんでもいいっす。

ターミナルで下記のことを聞かれます。

```
Choose your installation type 
❯ Quickstart (recommended) 
  Custom (manual settings) 
```
Quickstart (recommended)を選択しましょう。
strapiを勝手に作成してくれます。
10分ぐらいはかかります。待ちましょう。
ログが止まって途中であれ？っと思ってもしっかり待ちましょう。
腰を据えて待ちます。

<img width="612" alt="スクリーンショット 2019-12-17 5.41.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525860/57bb9c4a-1697-b56a-a158-78ee94fec95f.png">



こんなのがでてきたらOK
ログに出ている[http://localhost:1337/admin](http://localhost:1337/admin)へアクセスしてみましょう。

<img width="943" alt="スクリーンショット 2019-12-17 1.43.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525860/3fa6b856-17f6-c98f-f922-d7457ad49037.png">

こんな画面が出てきたら成功です。

情報を打ち込んで`Ready to start`を押します。
※一番下のチェックボックス入れるとstrapiの最新の情報をメールへお届けしてくれます。

<img width="1423" alt="スクリーンショット 2019-12-17 1.45.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525860/6522a063-4a21-d72c-6e5b-e6e43f377c1d.png">

さて、そんなこんなでこんな画面へきましたかね。

次に`コンテンツタイプを作成する`を押しましょう。

<img width="917" alt="スクリーンショット 2019-12-17 2.32.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525860/33d8438f-8de7-386a-9602-3d75a41e162c.png">


こんな画面へ遷移します。
一言で言えばDBのテーブル名を作成するところです。
DBはpostgresSQLを使うようにdocker-compose.ymlに記述されています。

今回は東京都の地区別の犯罪指数を作ることにします。
名前にcrimerateと入力して、接続はデフォルト、説明文を入れてあげます。
そしてdoneをクリック

<img width="911" alt="スクリーンショット 2019-12-17 2.34.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525860/9479ef8b-0e10-cf4d-7a44-ab1ac644d13c.png">

次はフィールド(カラム)のデータ型を決める画面に遷移します。
地区名が入るのでStringを選択します。

<img width="914" alt="スクリーンショット 2019-12-17 2.35.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525860/30dfa7f9-8384-9fc9-d010-22dafc826445.png">

カラム名をareaとしてdoneをクリック

<img width="1171" alt="スクリーンショット 2019-12-17 2.36.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525860/1c345a41-359a-4469-0922-f8e4672739d2.png">

画面が遷移してAreaというフィールド（カラム）が追加されたのが分かります。
もう一つ犯罪指数のフィールドを作るので`Add Another Field`をクリック

<img width="913" alt="スクリーンショット 2019-12-17 2.38.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525860/894a1806-1b4b-28b5-dadb-dfba1501f7d1.png">

指数は数値なのでNumberをクリック
<img width="914" alt="スクリーンショット 2019-12-17 2.40.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525860/7684f94a-83a2-e5c4-2de5-b6c84e5c3566.png">

名前（カラム名）にexponentsと入力して、数値形式はそのままでdone
<img width="1175" alt="スクリーンショット 2019-12-17 2.41.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525860/96640387-f64d-7609-7df1-f4bd6f636e33.png">

exponentsのフィールドが追加されました。
右上の保存をクリックします。
<img width="1096" alt="スクリーンショット 2019-12-17 2.24.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525860/cf496da4-d8aa-35e4-501e-28f01684cff1.png">

保存処理を待ちます。
<img width="1066" alt="スクリーンショット 2019-12-17 2.20.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525860/0deed97d-f657-b071-555e-7ecb80d003a4.png">
と、でればOK
少し待つと...
<img width="1426" alt="スクリーンショット 2019-12-17 2.43.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525860/8fa1365b-09a5-deae-0a52-e7ff9ca681d4.png">
画面が表示されます。
左のサイドバー(ダッシュボード)の上を見るとCrimerateと追加されました。

さて次は作ったフィールドに実際に値を入れよう
左のサイドバー(ダッシュボード)のCrimeratesを押します
<img width="1419" alt="スクリーンショット 2019-12-17 2.46.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525860/b6d3a98c-bbe1-7948-c3a7-ed2346f1af9c.png">

右上の "+ Crimerateを追加"をクリック
<img width="1421" alt="スクリーンショット 2019-12-17 2.47.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525860/5cb9279d-efe1-de5e-0da7-1cd37582c4dc.png">

ここでareaと指数に値を入れて保存をクリックします。
<img width="1425" alt="スクリーンショット 2019-12-17 2.48.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525860/1f7ad577-4a3a-024b-ff2f-01487a4a056d.png">

反映されました。

いくつかデータを入力しておきます。
<img width="1413" alt="スクリーンショット 2019-12-17 2.51.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525860/bbc3df81-2153-303a-0677-b5e7cf6f2b34.png">

お次は左のサイドバー(ダッシュボード)のロールと権限をクリック
<img width="1431" alt="スクリーンショット 2019-12-17 2.55.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525860/866eff3f-468a-ee0d-2d18-534e2fff9c6d.png">
publicを選択
<img width="1417" alt="スクリーンショット 2019-12-17 2.57.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525860/552403f6-2f51-9023-7fa8-3125ca9c3a7c.png">
権限のcreateとfindにチェックを入れて保存
※createやfindを誰でも使えるように許可するということをしています。
<img width="1417" alt="スクリーンショット 2019-12-17 3.03.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525860/4d0fb12f-9e23-77c5-cefb-3d2501b53f17.png">


## Strapiで作成したAPIを叩いてみる
さてAPIを叩きましょう。

もう一度ロールと権限のpublicをクリックしてfindの歯車をみつけてクリック
すると右の方に"Bound route to Crimerate.find"とある下に
`GET /crimerate`　とあります。
GETでcrimerateをfindする。取得するということ。
<img width="1390" alt="スクリーンショット 2019-12-17 3.01.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525860/ec0bf0b6-08de-ee0b-781b-f8f04bab5dbe.png">
とにかく[http://localhost:1337/crimerates](http://localhost:1337/crimerates)にアクセスしよう！
<img width="1418" alt="スクリーンショット 2019-12-17 3.12.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525860/186c6630-9f90-cbf4-cbb5-f83011b8f00e.png">

さきほど入力したデータをfind(取得)して表示されています。
ちなみにjsonviewってchromeの拡張ツール入れると...
<img width="645" alt="スクリーンショット 2019-12-17 3.14.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525860/3d9534f5-2bd4-af2e-a7be-d0d743d25b12.png">
いい感じに整形して表示してくれる

## axiosを利用してAPIを叩いてデータを登録
さて今度はPOSTでデータを登録するぞー。
POSTするにはブラウザからリクエストというのを想定するので...
axiosというライブラリを使ってサクッとPOSTしてやりましょう。
index.htmlをどこでもいいので作って以下のコードを貼っつけてファイルを保存しよう。
※areaに葛飾区、exponentsに4260という値がPOSTされるように記述しています。

```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>axios post</title>
</head>
<body>
<h1>axiosでPOST</h1>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
// POST通信
axios({
    method : 'POST',
    url    : 'http://localhost:1337/crimerates',
    data   : { area : '葛飾区', exponents : '4260' }
}).then(response => console.log(response.status));
</script>
</body>
</html>
```

保存できたらブラウザに読み込ませて検証ツールを開いてconsoleを見てみよう。
<img width="1413" alt="スクリーンショット 2019-12-17 3.54.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525860/7612e9b7-1bc0-8c69-bee0-ab476443337a.png">

200はHTTPのステータスコードでOK的なこと。
つまりaxiosによるPOSTのHTTPリクエストが成功したということ。

というわけでstrapiの管理画面でデータが入ったか確認しよう。
POSTしたデータはareaに葛飾区、exponentsに4260
<img width="1410" alt="スクリーンショット 2019-12-17 3.57.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525860/08aa70c3-48a8-2b76-8383-3bf6b25f14c4.png">
おー入ってます入ってます。

お疲れさまでした。

## おわりに
Strapiを使うと簡単にAPIを作ることができる。
今回はお試しハンズオンでした。高度な設定や、カスタムをすると結構いろんなことができるので、個人的にはプロトタイプの作成や簡易なものであればStrapiを利用したりします。
フロントをvue.jsで作成してStrapiでAPIを作成してSPAでRESTfulな開発もサッサとできてしまいます。
ドキュメントもどんどん充実していってるので使えるものは使っときましょう。