AWS Amplifyでkintoneに接続するAPIを最速で作成する

Amplify CLI を使うと、kintone REST API に接続する APIを簡単に作成することができます。

# 環境

* macOS 10.14.6

# データベースの準備
接続する先のデータベースにkintoneを利用します。

下記の感じで作ってください。

![スクリーンショット 2021-01-24 21.36.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214523/2d36bc2f-1651-ddc9-77a4-9cdb70d79e21.png)

（フィールド名・フィールドコード）/ （フィールドタイプ）
・owner / 文字列(1行)
・name / 文字列(1行)
・description / 文字列(1行)
・id / レコード番号
・createdAt / 作成日時
・updatedAt / 更新日時

## APIトークン取得

kintoneアプリの認証用にAPIトークンを取得しておきます。
今回のサンプルではレコード追加権限を追加したAPIトークンを利用します。

APIトークンを生成する
https://jp.cybozu.help/k/ja/user/app_settings/api_token.html

# Webフロントエンド作成

サンプルとしてReact Webアプリを作成して、kintoneにレコード登録するフォームを用意します。
create-react-app コマンドでReact Webアプリの雛形を作成します。
作成されたディレクトリに移動します。

```
$ npx create-react-app notessample
$ cd notessample
```


# API作成


## Amplifyのセットアップ

### Amplify CLIのインストール

Amplify CLI コマンドラインツールをローカルにインストールします。

```
$ npm install -g @aws-amplify/cli
```


### Amplify CLI の設定

`amplify configure` の実行

```
$ amplify configure

Scanning for plugins...
Plugin scan successful
Follow these steps to set up access to your AWS account:

Sign in to your AWS administrator account:
https://console.aws.amazon.com/
Press Enter to continue

Specify the AWS Region
? region:  ap-northeast-1
Specify the username of the new IAM user:
? user name:  amplify-0ZWUt
Press Enter to continue

Enter the access key of the newly created user:
? accessKeyId:  ********************
? secretAccessKey:  *****************************************
This would update/create the AWS Profile in your local machine
? Profile Name:  default

Successfully set up the new user.
```

### プロジェクト初期化

`amplify init` コマンドでバックエンド用のAmplifyプロジェクトを作成します。

```
$ amplify init
Note: It is recommended to run this command from the root of your app directory
? Enter a name for the project notessample　→　React Webアプリのディレクトリと同じにしておきます。
? Enter a name for the environment dev
? Choose your default editor: None
? Choose the type of app that you're building javascript
Please tell us about your project
? What javascript framework are you using none
? Source Directory Path:  src
? Distribution Directory Path: dist
? Build Command:  npm run-script build
? Start Command: npm run-script start
Using default provider  awscloudformation
・・・
? Do you want to use an AWS profile? Yes
? Please choose the profile you want to use default
・・・
```

## API追加

`amplify add api` API の追加
REST API と Lambda function の雛形を生成します。

```
$ amplify add api
? Please select from one of the below mentioned services: REST　→ REST API を選択
? Provide a friendly name for your resource to be used as a label for this category in the project: notessamp
leapi　→ APIの名前を指定します。設定した名前は、API Gateway の名前になります。 
? Provide a path (e.g., /book/{isbn}): /notes　→　API呼び出しのパス名を指定
? Choose a Lambda source Create a new Lambda function　→　新しくLambda functionを生成します。
? Provide an AWS Lambda function name: notessamplefunction　→　Lambda functionの名前を指定。
? Choose the runtime that you want to use: NodeJS　→　Lambda runtime はNodeJSを選択。
? Choose the function template that you want to use: Serverless ExpressJS function (Integration with API Gate
way) →　Lambda funcrion のテンプレートは Serverless ExpressJSを選択。

Available advanced settings:
- Resource access permissions
- Scheduled recurring invocation
- Lambda layers configuration

? Do you want to configure advanced settings? No
? Do you want to edit the local lambda function now? Yes
Successfully added resource notessamplefunction locally.
・・・
? Restrict API access No　→　注意。今回はサンプルなのでNoを選択。運用で利用する場合は別途認証機能を追加してください。
? Do you want to add another path? No
Successfully added resource notessampleapi locally
・・・
```

### Lambda function修正

・axiosライブラリのインストール
　kintoneにアクセスするHTTPクライアントにaxiosを使います。

　インストール先は "./amplify/backend/function/notessampleapi/src"
　※notessampleapiは amplify add api の Lambda function で設定した名前を指定。

```
$ npm install axios
```

---
・コードを修正

amplify/backend/function/notessamplefunction/src/app.js

```
var axios = require('axios')
var express = require('express')
・・・

// declare a new express app
var app = express()
app.use(bodyParser.json())
app.use(awsServerlessExpressMiddleware.eventContext())
・・・

/****************************
* Example post method *
****************************/

app.post('/notes', function(req, res) {
  const apitoken = '<kintone APIトークン>'; // kintoneのAPIトークンをセット
  const config = {
    headers: {
      'Content-Type': 'application/json',
      'X-Cybozu-API-Token': apitoken,
    },
  }
  axios.post('https://<sub-domain>.cybozu.com/k/v1/record.json', req.body, config)
  .then(response => {
    res.json({
      success: true,
      notes: response.data
    })
  })
  .catch(error => {
    res.json({
      success: false,
      error
    })
  })
});

app.post('/notes/*', function(req, res) {
  // Add your code here
  res.json({success: 'post call succeed!', url: req.url, body: req.body})
});
・・・
```

## バックエンドのデプロイ

APIとLambda functionをリモートにpushします。

`amplify push --y`

Amplifyにバックエンド環境が追加されます。


## フロントエンドのコードを修正

### Amplify ライブラリインストール

`npm install aws-amplify` 


### コード修正

雛形のコードを上書きします。

src/App.js

"app: 216"の 216はkintoneのアプリIDをセットします。

```
import React, { useState } from 'react';
import API from '@aws-amplify/api';
import Amplify from 'aws-amplify';
import config from './aws-exports';
import './App.css';

Amplify.configure(config);

const initialFormState = { id: '', name: '', description: '', owner: '' }

function App() {
  const [notes, setNotes] = useState([]);
  const [formData, setFormData] = useState(initialFormState);

  async function createNote() {
    console.log(formData);
    const myInit = {
      body: {
        app: 216,
        record: {
          name: {value: formData.name},
          description: {value: formData.description},
        }
      },
    };
    const result = await API.post('notessampleapi', '/notes', myInit);
    console.log(result);
    formData.id = result.notes.id;
    setNotes([ ...notes, formData ]);
    setFormData(initialFormState); 
    alert(JSON.stringify(result));
  }

  return (
    <div className="App">
      <p>My Note Sample</p>
      <form>
        <label>name :</label>
        <input
          type="text"
          id="name"
          onChange={e => setFormData({ ...formData, 'name': e.target.value})}
          value={formData.name}
        />
        <label>description :</label>
        <input
          type="text"
          id="description"
          onChange={e => setFormData({ ...formData, 'description': e.target.value})}
          value={formData.description}
        />
        <button type="button" onClick={createNote}>Create Note</button>
      </form>
    </div>
  );
}
export default App;
```

## フロントエンドのコードの紐付

### git push

GitHub等を使って、ローカルのコードをリモートにpushします。

```
git add .
git commit -m "initial commit"
git push origin master
```

### Amplify バックエンドにリポジトリを接続

Amplify consoleから、前段で作成されたAmplifyバックエンド環境にGitHubのリポジトリを接続します。

ビルド・デプロイ後に動作確認します。

AmplifyのホスティングURLが表示されるのでクリックして実行します。

# 動作確認

入力フォーム
![スクリーンショット 2021-02-07 22.42.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214523/bd0cf15b-ee31-c23c-26b8-59e1b586b1aa.png)

レコードの登録が成功すると、kintoneからのレコード登録の戻り値が表示されます。
![スクリーンショット 2021-02-07 22.45.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214523/243bed34-a823-19a8-2160-f5a747647c5f.png)


# 参考

・kintoneからのレコード取得、削除は下記を参考にしてください。
https://note.com/llc_luck/n/n99c270d59867