2020-10-20に更新

Next.jsとDgraphで作るクイズ・アプリ (4) データ形式とデータ通信

JSONを用いたデータのやり取り

今回はクライアントとAPIエンドポイントの間でのデータのやり取りの仕方をまとめておきます.

前回

前回を参照

APIエンドポイント一覧

以下のようなエンドポイントが必要になります.

API リソースの内容
GET base_url/api/quizzes クイズを取得する
POST base_url/api/quizzes 新規のクイズを作成する
GET base_url/api/quizzes/[uid] 指定したクイズの取得
DELETE base_url/api/quizzes/[uid] 指定したクイズの削除
PUT base_url/api/quizzes/[uid] 指定したクイズの更新

どんなデータをやり取りするか?

スキーマ

Dgraphではスキーマと呼ばれます.

Predicate Type
title string
user string
date datetime
question [uid]
answer [uid]
tags [string]

questionとanswerはtypeとcontentというstring型のプレディケートを持ちます.

---追記---

JSONの方が分かりやすと思います. 以下のようなJSONを登録すると上のようなスキーマが設定される感じです. なおanswerとquestionはDgraphでは別のノードとして管理されます. そのため[uid]のような型になるようです.

[
    {
        "title": "MonQとは何でしょうか?",
        "user": "brainvader",
        "version": "0.0.1",
        "date": "2020-10-08T18:01:00",
        "answer": [
            {
                "type": "text",
                "content": "MonQとは何でしょうか?"
            }
        ],
        "question": [
            {
                "type": "text",
                "content": "クイズベースの学習システムです."
            }
        ],
        "tags": [
            "monq"
        ]
    },
    {
        "title": "put on holdとは?",
        "user": "brainvader",
        "version": "0.0.1",
        "date": "2020-10-08T18:01:01",
        "answer": [
            {
                "type": "text",
                "content": "put on holdとは?"
            }
        ],
        "question": [
            {
                "type": "text",
                "content": "保留する"
            }
        ],
        "tags": [
            "english"
        ]
    }
]

こんな感じのデータがAPIを介してエディタとDBの間でやり取りされるわけです.

Next.jsにおけるデータ通信

サーバー側に送るデータはbodyに渡されます.

const createQuizHandler = async () => {
    const body = { data: 'test' }
    const res = await fetch('/api/quizzes', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(body)
    })
    const data = await res.json()
    console.log(`create quiz with uid: ${data.uid}`)
}

サーバー側ではreq.bodyとして参照できます. 値を返すときはjsonメソッドにJSオブジェクトを渡します. これがクライアント側ではres.jsonとして取得できます.

const addQuiz = async (req, res) => {
    const data = req.body.data
    console.log(`I've gottern ${data}`)

    res.statusCode = 200
    res.setHeader('Content-Type', 'application/json')
    res.json({ uid: '101' })
}

データのやり取りは非常に簡単ですね.

パス・パラメータ

クイズを作成しuidだけもらってエディタ上で開く場合pages/quizzes/[uid].jsというようにパス・パラメータを渡す必要があります. uidはクイズの生成時に動的に決まるのでルートも動的に指定する必要があるからです.

useRouterを使うと命令的にルーティングを実行することができ, この時にuidを指定することができるようになります. まずは読み込みます.

import { useRouter } from 'next/router'
const router = useRouter

routerのpushメソッドに以下のようにパス・パラメータを指定します.

router.push({
    pathname: '/quizzes/[uid]',
    query: { uid: uid },
})

これでuidの部分にuidとして渡した値が使われることになります.

With URL object

apiの場合はfetchなどの際に文字列テンプレートを使って挿入すればいいです.

const url = `api/quizzes${uid}`

サーバー側では以下のようにqueryオブジェクトから取得できます.

export default function handler(req, res) {
  const {
    query: { pid },
  } = req

  res.end(`Post: ${pid}`)
}

まとめ

あまり考えないでもNext.js側でやり方を強制してくるので, 使うのは難しくないと感じました.

次回

簡単にDgraphのクライアントの使い方をまとめます.

次回

Reference

router.push
Dynamic Routes
Dynamic API Routes

ツイッターでシェア
みんなに共有、忘れないようにメモ

ブレイン

Androidアプリ開発者を目指しています. 興味あることリスト: https://t.co/ew3bb6grdJ Github: https://t.co/9btqysHqWr Qiita: https://t.co/ZVRhjouauX

Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

有料記事を販売できるようになりました!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?

コメント