tag:crieit.net,2005:https://crieit.net/tags/Dgraph/feed
「Dgraph」の記事 - Crieit
Crieitでタグ「Dgraph」に投稿された最近の記事
2020-10-24T16:23:32+09:00
https://crieit.net/tags/Dgraph/feed
tag:crieit.net,2005:PublicArticle/16169
2020-10-24T16:23:32+09:00
2020-10-24T16:23:32+09:00
https://crieit.net/posts/Next-js-Dgraph-5-Dgraph
Next.jsとDgraphで作るクイズ・アプリ (5) Dgraphの基本
<h1 id="Dgraph操作の基本"><a href="#Dgraph%E6%93%8D%E4%BD%9C%E3%81%AE%E5%9F%BA%E6%9C%AC">Dgraph操作の基本</a></h1>
<h2 id="前回"><a href="#%E5%89%8D%E5%9B%9E">前回</a></h2>
<p><a href="https://crieit.net/posts/Next-js-Dgraph-4">前回</a>を参照</p>
<h2 id="用語"><a href="#%E7%94%A8%E8%AA%9E">用語</a></h2>
<p>グラフデータベースなので, ノードで構成されます.</p>
<div class="table-responsive"><table>
<thead>
<tr>
<th>用語</th>
<th>意味</th>
</tr>
</thead>
<tbody>
<tr>
<td>ノード</td>
<td>データを構成する基本要素. レコードのようなもの</td>
</tr>
<tr>
<td>プレディケート</td>
<td>ノードの属性やエッジ(ノード間の関係性)を表す</td>
</tr>
</tbody>
</table></div>
<h2 id="スキーマ"><a href="#%E3%82%B9%E3%82%AD%E3%83%BC%E3%83%9E">スキーマ</a></h2>
<p>とりあえず各ノードは以下のようなスキーマ持つとします.</p>
<div class="table-responsive"><table>
<thead>
<tr>
<th>Predicate</th>
<th>Data Type</th>
</tr>
</thead>
<tbody>
<tr>
<td>title</td>
<td>string</td>
</tr>
<tr>
<td>user</td>
<td>string</td>
</tr>
<tr>
<td>version</td>
<td>string</td>
</tr>
<tr>
<td>date</td>
<td>datetime</td>
</tr>
<tr>
<td>question</td>
<td>[uid]</td>
</tr>
<tr>
<td>answer</td>
<td>[uid]</td>
</tr>
<tr>
<td>tags</td>
<td>[uid]</td>
</tr>
</tbody>
</table></div>
<p>[uid]というのは別のノードを参照しているという意味で1対多の関係になります.</p>
<blockquote>
<p>UID arrays represent a collection of UIDs. This is used to represent one to many relationships.</p>
</blockquote>
<p><a target="_blank" rel="nofollow noopener" href="https://dgraph.io/docs/tutorial-3/#data-types-for-predicates">Data types for predicates</a></p>
<h3 id="question and answer nodes"><a href="#question+and+answer+nodes">question and answer nodes</a></h3>
<p>クイズの本体とも言える問とその答えです. 同じデータ構造で表現します.</p>
<div class="table-responsive"><table>
<thead>
<tr>
<th>Predicate</th>
<th>Data Type</th>
</tr>
</thead>
<tbody>
<tr>
<td>text</td>
<td>string</td>
</tr>
<tr>
<td>content</td>
<td>string</td>
</tr>
</tbody>
</table></div>
<h3 id="tags"><a href="#tags">tags</a></h3>
<p>クイズを分類するタグです. ノードで表現することで一意性をもたせることができます.</p>
<div class="table-responsive"><table>
<thead>
<tr>
<th>Predicate</th>
<th>Data Type</th>
</tr>
</thead>
<tbody>
<tr>
<td>tag_name</td>
<td>string</td>
</tr>
</tbody>
</table></div>
<h2 id="ミューテーション"><a href="#%E3%83%9F%E3%83%A5%E3%83%BC%E3%83%86%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3">ミューテーション</a></h2>
<p>データに変更を加えるにはsetとdeleteという2つのキーワードを使います.</p>
<h2 id="CRUD"><a href="#CRUD">CRUD</a></h2>
<h3 id="create"><a href="#create">create</a></h3>
<p>setはノードの作成とプレディケートの更新を行います.</p>
<pre><code class="json">{
"set": [
{
"title": "MonQとは何でしょうか?",
"user": "brainvader",
"version": "0.0.1",
"date": "2020-10-08T18:01:00",
"question": [
{
"type": "text",
"content": "MonQとは何でしょうか?"
},
{
"type": "text",
"content": "またどのようなものを目指しているでしょうか?"
}
],
"answer": [
{
"type": "text",
"content": "クイズベースの学習システムです."
},
{
"type": "text",
"content": "クイズ同士の寒冷性や依存性を定義することでクイズをモジュール化することを目指します."
}
],
"tags": [
{
"uid": "_:monq",
"tag_name": "monq"
}
]
}
]
}
</code></pre>
<p>作成されたノードには自動でuidが与えられます.</p>
<h3 id="read"><a href="#read">read</a></h3>
<p>クエリを用いて取得します. <a target="_blank" rel="nofollow noopener" href="https://dgraph.io/docs/query-language/functions/#has">has関数</a>を使うと指定したプレディケートを持っているノードを取得できます. func引数にhas関数を渡してやります.</p>
<pre><code>{
quizzes(func: has(title)) {
uid
title
user
date
version
question {
type
content
}
answer {
type
content
}
tags {
tag_name
}
}
}
</code></pre>
<p>ここでquizzesは関数名というよりはrootノードです. レスポンスは以下のようになります. quizzesという配列に取得したノードが収められています. 指定したルートノードから辿れるようにな構造になるわけです.</p>
<pre><code class="json">{
"data": {
"quizzes": [
...
]
}
...
}
</code></pre>
<p>以下のようなグラフが取得できます. ピンクがquとあるのでquestionで緑がanswer, そして紫がtagsです.中心の青はtitleを含むノードです. つまりクイズそのものを指します.</p>
<p><a href="https://crieit.now.sh/upload_images/c999c6bf95bbd99d341a53a9c5795a8a5f8e70a39720a.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/c999c6bf95bbd99d341a53a9c5795a8a5f8e70a39720a.png?mw=700" alt="image" /></a></p>
<h4 id="ブランク・ノード"><a href="#%E3%83%96%E3%83%A9%E3%83%B3%E3%82%AF%E3%83%BB%E3%83%8E%E3%83%BC%E3%83%89">ブランク・ノード</a></h4>
<p>ノードを指定する時にuidは自動で作られます. 作成後のノードには全てuidが付番されているので参照することは簡単です. 問題はノードを定義する時に共通のuidを指定したい場合です.</p>
<p>例えば共通のtagを持つクイズを同時に作りたい場合です. tagはノードとして管理されるのでuidで識別できます. 同じ文字列を指定しても同じノードを参照しているという関係は表せません. この場合_:identifierという表記を使うと同じuidであることを表せます.</p>
<p>以下は英単語の意味を問うよくあるクイズです. これらはどちらもenglishというタグ・ノードを参照するのが妥当でしょう.</p>
<pre><code class="json">{
"set": [
{
"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": [
{
"uid": "_:english",
"tag_name": "english"
}
]
},
{
"title": "hotshotとは?",
"user": "brainvader",
"version": "0.0.1",
"date": "2020-10-08T18:01:01",
"answer": [
{
"type": "text",
"content": "hotshotとは?"
}
],
"question": [
{
"type": "text",
"content": "有能な人、やり手, 凄腕"
}
],
"tags": [
{
"uid": "_:english",
"tag_name": "english"
}
]
}
]
}
</code></pre>
<p>先程のクエリを実行すると以下のようなグラフが得られます.</p>
<p><a href="https://crieit.now.sh/upload_images/a28995f869f3975eb5f4a6989755647e5f8e7341911b6.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/a28995f869f3975eb5f4a6989755647e5f8e7341911b6.png?mw=700" alt="image" /></a></p>
<p>englishというtagsノードを通じてつながっていることが分かります.</p>
<h3 id="delete"><a href="#delete">delete</a></h3>
<h4 id="ノードの削除"><a href="#%E3%83%8E%E3%83%BC%E3%83%89%E3%81%AE%E5%89%8A%E9%99%A4">ノードの削除</a></h4>
<p>よく分からん. とにかく消えないです.</p>
<h4 id="プレディケーとの削除"><a href="#%E3%83%97%E3%83%AC%E3%83%87%E3%82%A3%E3%82%B1%E3%83%BC%E3%81%A8%E3%81%AE%E5%89%8A%E9%99%A4">プレディケーとの削除</a></h4>
<p>更新処理の前に削除をしてみましょう. 各ノードにはプレディケートというフィールドに該当するものが存在する. ノードをuidで指定してプレディケートをnullに指定するとそのプレディケートは削除されたことになります. 全てのプレディケートがなくなるとそのノードは削除されたとみなされます(とされていますが, コンソールで試すと消えません).</p>
<p>ノードの場合は単純にuidを指定すれば良いようです.</p>
<p>さて先程の英単語のクイズを削除してみましょう. 以下のようなミューテーションを実行します.</p>
<pre><code class="json">{
"delete": [
{
"uid": "0x3a982",
"title": null,
"answer": null,
"question": null,
"tags": null
}
]
}
</code></pre>
<p>この場合tagsは他方のクイズからも消えてしまうでしょうか? このノードからは辿れなくなりますが, ノード自体は残ります.</p>
<h4 id="プレディケートの全削除"><a href="#%E3%83%97%E3%83%AC%E3%83%87%E3%82%A3%E3%82%B1%E3%83%BC%E3%83%88%E3%81%AE%E5%85%A8%E5%89%8A%E9%99%A4">プレディケートの全削除</a></h4>
<p>以下のような記法を使います.</p>
<pre><code>{
delete {
<0x3a985> * * .
}
}
</code></pre>
<p>プレディケートのフィールド名を使うこともできます.</p>
<pre><code>{
delete {
<0x3a985> <title> * .
}
}
</code></pre>
<p>こえでtitleプレディケートは消せます.</p>
<h3 id="update"><a href="#update">update</a></h3>
<h4 id="プロパティ・プレディケート"><a href="#%E3%83%97%E3%83%AD%E3%83%91%E3%83%86%E3%82%A3%E3%83%BB%E3%83%97%E3%83%AC%E3%83%87%E3%82%A3%E3%82%B1%E3%83%BC%E3%83%88">プロパティ・プレディケート</a></h4>
<p>単純に値を上書きすれば良いようです. userの名前を変更してみましょう.</p>
<pre><code class="json">{
"set": [
{
"uid": "0x3a985",
"user": "no-brainer"
}
]
}
</code></pre>
<p>ではuser名を取得してみましょう.</p>
<pre><code>{
quizzes(func: uid(0x3a985)) {
user
}
}
</code></pre>
<p>user名がbrainvaderからno-brainerに変わっているのが分かります.</p>
<p><a href="https://crieit.now.sh/upload_images/ce43595fe29e31547cdeb53c66b173d75f8e815697351.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/ce43595fe29e31547cdeb53c66b173d75f8e815697351.png?mw=700" alt="image" /></a></p>
<h4 id="エッジ・プレディケート"><a href="#%E3%82%A8%E3%83%83%E3%82%B8%E3%83%BB%E3%83%97%E3%83%AC%E3%83%87%E3%82%A3%E3%82%B1%E3%83%BC%E3%83%88">エッジ・プレディケート</a></h4>
<p>おなじみのクイズを作ってみましょう.</p>
<pre><code class="json">{
"set": [
{
"title": "MonQとは何でしょうか?",
"user": "brainvader",
"version": "0.0.1",
"date": "2020-10-08T18:01:00",
"question": [
{
"type": "text",
"content": "MonQとは何でしょうか?"
},
{
"type": "text",
"content": "またどのようなものを目指しているでしょうか?"
}
],
"answer": [
{
"type": "text",
"content": "クイズベースの学習システムです."
},
{
"type": "text",
"content": "クイズ同士の寒冷性や依存性を定義することでクイズをモジュール化することを目指します."
}
],
"tags": [
{
"tag_name": "monq"
}
]
}
]
}
</code></pre>
<p>tagを更新して見ます.</p>
<pre><code class="json">{
"set": [
{
"uid": "0x3a992",
"tags" : {
"tag_name": "tutorial"
}
}
]
}
</code></pre>
<p>新しくtutorialというtagが追加されたことが分かります.</p>
<pre><code>{
quizzes(func: has(tag_name)) {
tag_name
}
}
</code></pre>
<h2 id="Q&A"><a href="#Q%26amp%3BA">Q&A</a></h2>
<h3 id="プレディケートの前に付く~(ティルダ)の意味とは?"><a href="#%E3%83%97%E3%83%AC%E3%83%87%E3%82%A3%E3%82%B1%E3%83%BC%E3%83%88%E3%81%AE%E5%89%8D%E3%81%AB%E4%BB%98%E3%81%8F%7E%28%E3%83%86%E3%82%A3%E3%83%AB%E3%83%80%29%E3%81%AE%E6%84%8F%E5%91%B3%E3%81%A8%E3%81%AF%3F">プレディケートの前に付く~(ティルダ)の意味とは?</a></h3>
<p>エッジの方向を反対に探索することを意味する.</p>
<h3 id="anyofterms(predicate, "query word")"><a href="#anyofterms%28predicate%2C+%26quot%3Bquery+word%26quot%3B%29">anyofterms(predicate, "query word")</a></h3>
<p>プレディケーとがqueryかwordにマッチする.</p>
<h2 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h2>
<ul>
<li>uid(value)</li>
<li>has(predicate)</li>
<li>gt(predicate, value)</li>
<li>@recurse(depth: value)</li>
<li>@filter(lt(dislikes, 10))</li>
<li>eq(tag_name,"devrel")</li>
</ul>
<h2 id="クエリ集"><a href="#%E3%82%AF%E3%82%A8%E3%83%AA%E9%9B%86">クエリ集</a></h2>
<h3 id="タグの取得"><a href="#%E3%82%BF%E3%82%B0%E3%81%AE%E5%8F%96%E5%BE%97">タグの取得</a></h3>
<pre><code>{
all_tags(func: has(tag_name)) {
tag_name
}
}
</code></pre>
<h3 id="特定のタグの削除"><a href="#%E7%89%B9%E5%AE%9A%E3%81%AE%E3%82%BF%E3%82%B0%E3%81%AE%E5%89%8A%E9%99%A4">特定のタグの削除</a></h3>
<p>プロパティ・プレディケートがなくなると削除されるので唯一のプレディケートであるtag_nameをnullに設定すれば良い.</p>
<p>```json<br />
{<br />
"delete": [<br />
{<br />
"uid": "0x3a992",<br />
"tags" : [{<br />
"uid" : "0x3a994",<br />
"tag_name": null<br />
}<br />
]<br />
}<br />
]<br />
}</p>
ブレイン
tag:crieit.net,2005:PublicArticle/16125
2020-10-11T19:07:14+09:00
2020-10-20T10:56:23+09:00
https://crieit.net/posts/Next-js-Dgraph-4
Next.jsとDgraphで作るクイズ・アプリ (4) データ形式とデータ通信
<h1 id="JSONを用いたデータのやり取り"><a href="#JSON%E3%82%92%E7%94%A8%E3%81%84%E3%81%9F%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E3%82%84%E3%82%8A%E5%8F%96%E3%82%8A">JSONを用いたデータのやり取り</a></h1>
<p>今回はクライアントとAPIエンドポイントの間でのデータのやり取りの仕方をまとめておきます.</p>
<h2 id="前回"><a href="#%E5%89%8D%E5%9B%9E">前回</a></h2>
<p><a href="https://crieit.net/posts/Next-js-Dgraph-3-API-next-connect">前回</a>を参照</p>
<h2 id="APIエンドポイント一覧"><a href="#API%E3%82%A8%E3%83%B3%E3%83%89%E3%83%9D%E3%82%A4%E3%83%B3%E3%83%88%E4%B8%80%E8%A6%A7">APIエンドポイント一覧</a></h2>
<p>以下のようなエンドポイントが必要になります.</p>
<div class="table-responsive"><table>
<thead>
<tr>
<th>API</th>
<th>リソースの内容</th>
</tr>
</thead>
<tbody>
<tr>
<td>GET base_url/api/quizzes</td>
<td>クイズを取得する</td>
</tr>
<tr>
<td>POST base_url/api/quizzes</td>
<td>新規のクイズを作成する</td>
</tr>
<tr>
<td>GET base_url/api/quizzes/[uid]</td>
<td>指定したクイズの取得</td>
</tr>
<tr>
<td>DELETE base_url/api/quizzes/[uid]</td>
<td>指定したクイズの削除</td>
</tr>
<tr>
<td>PUT base_url/api/quizzes/[uid]</td>
<td>指定したクイズの更新</td>
</tr>
</tbody>
</table></div>
<h2 id="どんなデータをやり取りするか?"><a href="#%E3%81%A9%E3%82%93%E3%81%AA%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E3%82%84%E3%82%8A%E5%8F%96%E3%82%8A%E3%81%99%E3%82%8B%E3%81%8B%3F">どんなデータをやり取りするか?</a></h2>
<h3 id="スキーマ"><a href="#%E3%82%B9%E3%82%AD%E3%83%BC%E3%83%9E">スキーマ</a></h3>
<p>Dgraphではスキーマと呼ばれます.</p>
<div class="table-responsive"><table>
<thead>
<tr>
<th>Predicate</th>
<th>Type</th>
</tr>
</thead>
<tbody>
<tr>
<td>title</td>
<td>string</td>
</tr>
<tr>
<td>user</td>
<td>string</td>
</tr>
<tr>
<td>date</td>
<td>datetime</td>
</tr>
<tr>
<td>question</td>
<td>[uid]</td>
</tr>
<tr>
<td>answer</td>
<td>[uid]</td>
</tr>
<tr>
<td>tags</td>
<td>[string]</td>
</tr>
</tbody>
</table></div>
<p>questionとanswerはtypeとcontentというstring型のプレディケートを持ちます.</p>
<p>---追記---</p>
<h3 id="例"><a href="#%E4%BE%8B">例</a></h3>
<p>JSONの方が分かりやすと思います. 以下のようなJSONを登録すると上のようなスキーマが設定される感じです. なおanswerとquestionはDgraphでは別のノードとして管理されます. そのため[uid]のような型になるようです.</p>
<pre><code class="json">[
{
"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"
]
}
]
</code></pre>
<p>こんな感じのデータがAPIを介してエディタとDBの間でやり取りされるわけです.</p>
<h2 id="Next.jsにおけるデータ通信"><a href="#Next.js%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E9%80%9A%E4%BF%A1">Next.jsにおけるデータ通信</a></h2>
<p>サーバー側に送るデータはbodyに渡されます.</p>
<pre><code class="javascript">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}`)
}
</code></pre>
<p>サーバー側ではreq.bodyとして参照できます. 値を返すときはjsonメソッドにJSオブジェクトを渡します. これがクライアント側ではres.jsonとして取得できます.</p>
<pre><code class="javascript">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' })
}
</code></pre>
<p>データのやり取りは非常に簡単ですね.</p>
<h3 id="パス・パラメータ"><a href="#%E3%83%91%E3%82%B9%E3%83%BB%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF">パス・パラメータ</a></h3>
<p>クイズを作成しuidだけもらってエディタ上で開く場合pages/quizzes/[uid].jsというようにパス・パラメータを渡す必要があります. uidはクイズの生成時に動的に決まるのでルートも動的に指定する必要があるからです.</p>
<p>useRouterを使うと命令的にルーティングを実行することができ, この時にuidを指定することができるようになります. まずは読み込みます.</p>
<pre><code class="javascript">import { useRouter } from 'next/router'
const router = useRouter
</code></pre>
<p>routerのpushメソッドに以下のようにパス・パラメータを指定します.</p>
<pre><code class="javascript">router.push({
pathname: '/quizzes/[uid]',
query: { uid: uid },
})
</code></pre>
<p>これでuidの部分にuidとして渡した値が使われることになります.</p>
<p><a target="_blank" rel="nofollow noopener" href="https://nextjs.org/docs/api-reference/next/router#with-url-object">With URL object</a></p>
<p>apiの場合はfetchなどの際に文字列テンプレートを使って挿入すればいいです.</p>
<pre><code class="javascript">const url = `api/quizzes${uid}`
</code></pre>
<p>サーバー側では以下のようにqueryオブジェクトから取得できます.</p>
<pre><code class="javascript">export default function handler(req, res) {
const {
query: { pid },
} = req
res.end(`Post: ${pid}`)
}
</code></pre>
<h2 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h2>
<p>あまり考えないでもNext.js側でやり方を強制してくるので, 使うのは難しくないと感じました.</p>
<h2 id="次回"><a href="#%E6%AC%A1%E5%9B%9E">次回</a></h2>
<p>簡単にDgraphのクライアントの使い方をまとめます.</p>
<p>次回</p>
<h2 id="Reference"><a href="#Reference">Reference</a></h2>
<p><a target="_blank" rel="nofollow noopener" href="https://nextjs.org/docs/api-reference/next/router#routerpush">router.push</a><br />
<a target="_blank" rel="nofollow noopener" href="https://nextjs.org/docs/routing/dynamic-routes">Dynamic Routes</a><br />
<a target="_blank" rel="nofollow noopener" href="https://nextjs.org/docs/api-routes/dynamic-api-routes">Dynamic API Routes</a></p>
ブレイン
tag:crieit.net,2005:PublicArticle/16124
2020-10-11T18:11:02+09:00
2020-10-11T19:07:40+09:00
https://crieit.net/posts/Next-js-Dgraph-3-API-next-connect
Next.jsとDgraphで作るクイズ・アプリ (3) APIルートの設定とnext-connect
<h1 id="APIの設定"><a href="#API%E3%81%AE%E8%A8%AD%E5%AE%9A">APIの設定</a></h1>
<p>今回はAPIルートを使って簡単なバックエンドを作ります.</p>
<h2 id="前回"><a href="#%E5%89%8D%E5%9B%9E">前回</a></h2>
<p><a href="https://crieit.net/posts/Next-js-Dgraph-2">前回</a>を参照</p>
<h2 id="APIルートの設定"><a href="#API%E3%83%AB%E3%83%BC%E3%83%88%E3%81%AE%E8%A8%AD%E5%AE%9A">APIルートの設定</a></h2>
<h3 id="APIルートとは?"><a href="#API%E3%83%AB%E3%83%BC%E3%83%88%E3%81%A8%E3%81%AF%3F">APIルートとは?</a></h3>
<p>Next.jsが提供する機能でAPIエンドポイントが作れます. まずpagesフォルダ以下にapiというフォルダを作ります. この中にハンドラを定義します. フォルダのパスがそのままAPIのパスとして使われます.</p>
<p>例えばapi/quizzes.jsなら</p>
<p><a target="_blank" rel="nofollow noopener" href="http://localhost:3000/api/quizzes">http://localhost:3000/api/quizzes</a></p>
<p>としてアクセスできます.</p>
<h3 id="ハンドラのシグニチャ"><a href="#%E3%83%8F%E3%83%B3%E3%83%89%E3%83%A9%E3%81%AE%E3%82%B7%E3%82%B0%E3%83%8B%E3%83%81%E3%83%A3">ハンドラのシグニチャ</a></h3>
<p>ハンドラはリクエストを受け取ってレスポンスを返すような非同期関数です.</p>
<pre><code class="javascript">const handler = async (req, res) => {
// do something with local file system, database, or external apis
}
</code></pre>
<p>これをファイルの末尾でエクスポートしておくだけです.</p>
<pre><code>export default handler
</code></pre>
<h3 id="HTTPメソッド"><a href="#HTTP%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89">HTTPメソッド</a></h3>
<p>api/quizzesエンドポイントではクイズの取得, クイズの作成ができます. これらはHTTPメソッドの違いで区別されるわけです. メソッドはreq.methodで参照できます.</p>
<pre><code class="javascript">export default function handler(req, res) {
if (req.method === 'POST') {
// Process a POST request
} else {
// Handle any other HTTP method
}
}
</code></pre>
<p><a target="_blank" rel="nofollow noopener" href="https://nextjs.org/docs/api-routes/introduction">API Routes</a></p>
<p>これは少しめんどくさいです. next-connectを使うともう少し整理した書き方が出来るようになります.</p>
<h2 id="dgraph-js-http"><a href="#dgraph-js-http">dgraph-js-http</a></h2>
<p>DgraphへのアクセスはJavaScriptクライアントの<a target="_blank" rel="nofollow noopener" href="https://github.com/dgraph-io/dgraph-js-http">dgraph-js-http</a>を使います.</p>
<h3 id="インストール"><a href="#%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB">インストール</a></h3>
<pre><code>npm i dgraph-js-http
</code></pre>
<h3 id="読み込み"><a href="#%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%81%BF">読み込み</a></h3>
<pre><code>import * as dgraph from 'dgraph-js-http'
</code></pre>
<h3 id="クライアントの作成"><a href="#%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88%E3%81%AE%E4%BD%9C%E6%88%90">クライアントの作成</a></h3>
<p>その前にDgraph ZeroのURLを.env.localに保存しておきましょう.</p>
<pre><code>DGRAPH_URL='http://localhost:8080/'
</code></pre>
<p>これを使いクライアントを作成します. DgraphClientStubは第一引数にアドレスを取ります.</p>
<pre><code>function DgraphClientStub(addr, stubConfig, options) {
...
}
</code></pre>
<p>このインスタンスをDgraphClientに渡します.</p>
<pre><code>const clientStub = new dgraph.DgraphClientStub(process.env.DGRAPH_URL)
const dgraphClient = new dgraph.DgraphClient(clientStub)
</code></pre>
<h2 id="next-connect"><a href="#next-connect">next-connect</a></h2>
<p>実際にデータをやり取りするにはHTTPメソッドの指定が必要です. またその度にクライアントを作成するのも面倒です. next-connectを使うとHTTPメソッドごとのハンドラのヒモ付やDBクライアント取得処理をミドルウェア化できます. 内部的にはtrouterという機能を使っているようです.</p>
<h3 id="導入"><a href="#%E5%B0%8E%E5%85%A5">導入</a></h3>
<pre><code>npm i next-connect
</code></pre>
<h3 id="ミドルウェア"><a href="#%E3%83%9F%E3%83%89%E3%83%AB%E3%82%A6%E3%82%A7%E3%82%A2">ミドルウェア</a></h3>
<p>middlware/database.js</p>
<pre><code class="javascript">import * as dgraph from 'dgraph-js-http'
import nextConnect from 'next-connect';
const clientStub = new dgraph.DgraphClientStub(process.env.DGRAPH_URL)
const dgraphClient = new dgraph.DgraphClient(clientStub)
async function database(req, res, next) {
req.dbClient = dgraphClient;
return next();
}
const middleware = nextConnect();
middleware.use(database);
export default middleware;
</code></pre>
<p>dbClientとして参照出来るようになります. ハンドラ側ではミドルウェアを利用するようにします.</p>
<pre><code class="javascript">import nextConnect from 'next-connect';
import middleware from '../../../middleware/database';
const handler = nextConnect();
handler.use(middleware);
export default handler;
</code></pre>
<h3 id="ハンドラの登録"><a href="#%E3%83%8F%E3%83%B3%E3%83%89%E3%83%A9%E3%81%AE%E7%99%BB%E9%8C%B2">ハンドラの登録</a></h3>
<p>各メソッド毎にハンドラを登録できるようになりました.</p>
<pre><code class="javascript">const getHandler = async (req, res) => { /*...*/ }
handler.get(getHandler)
</code></pre>
<p>これで</p>
<pre><code>GET http://localhost:8080/api/quizzes
POST http://localhost:8080/api/quizzes
</code></pre>
<p>を使い分けることができるようになりました.</p>
<h3 id="Dgraphクライアントへのアクセス"><a href="#Dgraph%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88%E3%81%B8%E3%81%AE%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9">Dgraphクライアントへのアクセス</a></h3>
<p>reqから参照できます.</p>
<pre><code class="javascript">const getQuizzes = async (req, res) => {
const client = req.dbClient
}
</code></pre>
<h2 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h2>
<p>next-connectを使うことでHTTPメソッドとハンドラの関係性が記述しやすくなったかなと思います.</p>
<h2 id="次回"><a href="#%E6%AC%A1%E5%9B%9E">次回</a></h2>
<p><a href="https://crieit.net/posts/Next-js-Dgraph-4">次回</a>を参照</p>
<h2 id="Reference"><a href="#Reference">Reference</a></h2>
<p><a target="_blank" rel="nofollow noopener" href="https://vercel.com/guides/deploying-next-and-mysql-with-vercel">Create a Next.js App with a MySQL Database That Builds and Deploys with Vercel</a><br />
<a target="_blank" rel="nofollow noopener" href="https://developer.mongodb.com/how-to/nextjs-building-modern-applications">Building Modern Applications with Next.js and MongoDB</a><br />
<a target="_blank" rel="nofollow noopener" href="https://qiita.com/insight3110/items/5514f41404ce2036bd87">Next.jsのAPI Routerを使ってMongoDBからデータを引っ張ってくるAPIを作る(next-connectを利用したミドルウェアも)</a></p>
ブレイン
tag:crieit.net,2005:PublicArticle/16123
2020-10-11T17:22:58+09:00
2020-10-11T18:11:37+09:00
https://crieit.net/posts/Next-js-Dgraph-2
Next.jsとDgraphで作るクイズ・アプリ (2) プロジェクトの環境構築
<h1 id="プロジェクトの構築"><a href="#%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AE%E6%A7%8B%E7%AF%89">プロジェクトの構築</a></h1>
<p>今回からはプロジェクトを構築していく.</p>
<h2 id="前回"><a href="#%E5%89%8D%E5%9B%9E">前回</a></h2>
<p><a href="https://crieit.net/posts/Next-js-Dgraph-1">前回</a>を参照</p>
<h2 id="前提条件"><a href="#%E5%89%8D%E6%8F%90%E6%9D%A1%E4%BB%B6">前提条件</a></h2>
<ul>
<li>Node.js入ってる?</li>
<li>Gitが入ってる?</li>
<li>Docker入ってる?</li>
</ul>
<h2 id="Next.js"><a href="#Next.js">Next.js</a></h2>
<p>Next.jsの環境構築は簡単です. create-react-appのようにcreate-next-appを使うとプロジェクト・テンプレートが生成されます.</p>
<pre><code>npm i -g create-next-app
</code></pre>
<p>必要ならログイン・シェルを再起動します.</p>
<pre><code>exec $SHELL -l
</code></pre>
<p>後は適当にプロジェクト名を決めて実行するだけです.</p>
<pre><code>create-next-app minq-editor --use-npm
</code></pre>
<p>ターミナルなどで以下を実行してアプリケーションを起動しましょう.</p>
<pre><code class="shell">npm run dev
</code></pre>
<h2 id="Dgraphクラスタの起動"><a href="#Dgraph%E3%82%AF%E3%83%A9%E3%82%B9%E3%82%BF%E3%81%AE%E8%B5%B7%E5%8B%95">Dgraphクラスタの起動</a></h2>
<p><a href="https://crieit.net/posts/Dgraph">無心でDgraph入門</a>を参照</p>
<pre><code>docker run --name myq -v minq:/dgraph --rm -it -p 8080:8080 -p 9080:9080 -p 8000:8000 dgraph/standalone:v20.03.0
</code></pre>
<p>コンテナの名前, ボリュームの名前, ポート番号などは適当に変えましょう.</p>
<h2 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h2>
<p>環境の構築は非常に簡単ですね.</p>
<p><a href="https://crieit.net/posts/Next-js-Dgraph-3-API-next-connect">次回</a></p>
<h2 id="Reference"><a href="#Reference">Reference</a></h2>
<p><a target="_blank" rel="nofollow noopener" href="https://shinkufencer.hateblo.jp/entry/2018/11/22/233000">exec $SHELL -l でシェルが再読込されるしくみ</a></p>
ブレイン
tag:crieit.net,2005:PublicArticle/16122
2020-10-11T16:01:46+09:00
2020-10-11T16:01:46+09:00
https://crieit.net/posts/Next-js-Dgraph-1
Next.jsとDgraphで作るクイズ・アプリ (1) アプリの構想
<h1 id="アプリの構想"><a href="#%E3%82%A2%E3%83%97%E3%83%AA%E3%81%AE%E6%A7%8B%E6%83%B3">アプリの構想</a></h1>
<h2 id="どんなアプリか?"><a href="#%E3%81%A9%E3%82%93%E3%81%AA%E3%82%A2%E3%83%97%E3%83%AA%E3%81%8B%3F">どんなアプリか?</a></h2>
<p>クイズ・アプリなのでクイズができるアプリになる予定ですが, どちらかというとクイズベースの学習システムと考えています. クイズという名前も通りが良いから使ってるだけで実際は問です. ここで問とは答えがあるものを指します.</p>
<p>基本的な機能としては,</p>
<ul>
<li>クイズ・データベース</li>
<li>テスト</li>
<li>成績管理</li>
<li>スキル・マップ</li>
<li>レコメンド</li>
<li>サーティフィケート</li>
</ul>
<p>ができたら良いなぁと思っています. レコメンドやらサーティフィケートとかは現時点では構想というよりは誇大妄想的な感じもします(金力もないですしね). 能力の可視化ができたらとりあえずは完成でしょうか.</p>
<h2 id="何故クイズ?"><a href="#%E4%BD%95%E6%95%85%E3%82%AF%E3%82%A4%E3%82%BA%3F">何故クイズ?</a></h2>
<p>なんかの本でクイズ(練習問題)が効率的な学習法だと読んだからです. 本は忘れましたが多分以下のどれかの本です.</p>
<p><a target="_blank" rel="nofollow noopener" href="http://www.eijipress.co.jp/book/book.php?epcode=2258">『Learn Better』</a><br />
<a target="_blank" rel="nofollow noopener" href="https://www.diamond.co.jp/book/9784478021835.html">『脳が認める勉強法』</a><br />
<a target="_blank" rel="nofollow noopener" href="https://d21.co.jp/book/detail/978-4-7993-1685-6">『「学力」の経済学 』</a></p>
<h2 id="技術スタック"><a href="#%E6%8A%80%E8%A1%93%E3%82%B9%E3%82%BF%E3%83%83%E3%82%AF">技術スタック</a></h2>
<p>上記のことをクリアするには, いろんな技術が必要になります. 当面はクイズ風のブログという感じで公開して行く予定ですが以下のような技術(というかライブラリやらフレームワークやらSaaS)を使う予定です.</p>
<ul>
<li>Next.js</li>
<li>Netlify</li>
<li>Semantic UI React</li>
<li>Dgraph</li>
</ul>
<p>他にも以下を検討中です.</p>
<ul>
<li>モバイル (Android)</li>
<li>SaaS</li>
</ul>
<h3 id="選定理由・用途"><a href="#%E9%81%B8%E5%AE%9A%E7%90%86%E7%94%B1%E3%83%BB%E7%94%A8%E9%80%94">選定理由・用途</a></h3>
<h4 id="Next.js & Jamstack"><a href="#Next.js+%26amp%3B+Jamstack">Next.js & Jamstack</a></h4>
<p>Next.jsはクイズ用のエディタの作成やクイズの公開に使いたいと思います.</p>
<p>Next.jsはSPA(Single Page Application)からSSR(Server Side Rendering)そしてJamstackまでカバーしたWebアプリケーション・フレームワークです. Jamstackというのはwebサイトやwebアプリケーション開発のアーキテクチャの一つです.</p>
<blockquote>
<p>Jamstack is an architecture designed to make the web faster, more secure, and easier to scale.</p>
</blockquote>
<p>もともとはJavaScript, APIs, Markupから作られた造語です. フロントは静的サイト・ジェネレータ(Markup)で静的なファイル(HTML)として作ってCDNで配布, 動的な部分はJavaScriptとAPIsを使って更新するというような考え方です. ある意味Ajaxへの回帰と言えるでしょうか.</p>
<p><img src="https://d33wubrfki0l68.cloudfront.net/b7d16f7f3654fb8572360301e60d76df254a323e/385ec/img/svg/architecture.svg" alt="image" /></p>
<p>Next.jsのポイントはページをReactアプリケーションとして構築できるところです. React自体はUIライブラリという位置づけだったのでWebアプリケーション開発となると面倒なことも多かったです. Reactやって, クライアントサイド・ルーティング勉強して, 別個にAPIサーバーを立ててなどと考える必要はなく, 一つのフレームワークで完結します.</p>
<p>Next.jsならファイル・パスとルートが対応したり, API(バックエンド)も作れたりと考えることが少なくて良いです. 過去この点で何度も失敗しているのでNext.jsを触ったときは感動しました.</p>
<p>またNext.jsを作っているVercelのホスティング・サービスを使えばサイトのデプロイや配信なども簡単にできるので技術ブログなんかにはちょうど良いのかもしれません.</p>
<p>個人的には簡易なサーバーからフロントエンドまで完結する点を評価してエディタの開発に採用しました(これだけ流行っているフレームワークなので小賢しい後付に近いですが).</p>
<h4 id="Netlify"><a href="#Netlify">Netlify</a></h4>
<p>Netlifyの何かが良かったのですが忘れてしまいました.</p>
<h4 id="Semantic UI React"><a href="#Semantic+UI+React">Semantic UI React</a></h4>
<p>手頃のUIコンポーネントが欲しかったので適当に選びました.</p>
<h4 id="Dgraph"><a href="#Dgraph">Dgraph</a></h4>
<p>クイズ間の関係性/依存性が記述できるようなデータベースが良いと思って探していてちょうど見つけたのがDgraphでした. とりあえず静的ファイルのデータソースとして使う文には問題なさそうです. クラウド・サービスもあるようなのでちょっと気になるところです.</p>
<h4 id="モバイル (Android)"><a href="#%E3%83%A2%E3%83%90%E3%82%A4%E3%83%AB+%28Android%29">モバイル (Android)</a></h4>
<p>当然スマフォで空き時間に勉強できたら便利です. モバイルならとりあえずは成績の管理とかはスマフォ側のストレージでできそうです. Google Driveとかに保存しても良いかもしれません.</p>
<p>モバイル開発ではトレンド的にはFlutterなどが注目を集めています. ReactやってるならReact-nativeとかでもいいし, 用途的にはUnityとかでも良いのかもしれません. Android版に限定する予定なので, ネイティブとしても良いのかもしれません. 作ることだけが決めていますがよく分かりません.</p>
<h4 id="GS2"><a href="#GS2">GS2</a></h4>
<p>ゲーム用のSaaSです. Playfabとかもあるようです. GS2は日本製で条件付きで売上1000万まで無料で使えるので安心して使えるかなとGS2に傾きつつある昨今です.</p>
<h2 id="Reference"><a href="#Reference">Reference</a></h2>
<p><a target="_blank" rel="nofollow noopener" href="https://nextjs.org/">Next.js</a><br />
<a target="_blank" rel="nofollow noopener" href="https://dgraph.io/">Dgraph</a><br />
<a target="_blank" rel="nofollow noopener" href="https://jamstack.org/">Jamstack</a><br />
<a target="_blank" rel="nofollow noopener" href="https://reactnative.dev/">React Native</a><br />
<a target="_blank" rel="nofollow noopener" href="https://flutter.dev/?gclid=Cj0KCQjwt4X8BRCPARIsABmcnOry5Uy1LKLGR43-ZnRuX60vTy5JMG6NFhkF7Z0wPhXeS-5tpmO48wUaAjssEALw_wcB&gclsrc=aw.ds">Flutter</a><br />
<a target="_blank" rel="nofollow noopener" href="https://unity.com/">Unity</a></p>
ブレイン
tag:crieit.net,2005:PublicArticle/16117
2020-10-06T20:49:24+09:00
2020-10-09T22:17:25+09:00
https://crieit.net/posts/Dgraph
無心でDgraph入門
<h1 id="Dgraphの起動とスキーマ定義"><a href="#Dgraph%E3%81%AE%E8%B5%B7%E5%8B%95%E3%81%A8%E3%82%B9%E3%82%AD%E3%83%BC%E3%83%9E%E5%AE%9A%E7%BE%A9">Dgraphの起動とスキーマ定義</a></h1>
<h2 id="目標"><a href="#%E7%9B%AE%E6%A8%99">目標</a></h2>
<p>とりあえず動かすして遊べるようにする.</p>
<h2 id="前提"><a href="#%E5%89%8D%E6%8F%90">前提</a></h2>
<ul>
<li>Dockerのインストール</li>
</ul>
<h2 id="Dgraphクラスタの構造"><a href="#Dgraph%E3%82%AF%E3%83%A9%E3%82%B9%E3%82%BF%E3%81%AE%E6%A7%8B%E9%80%A0">Dgraphクラスタの構造</a></h2>
<div class="table-responsive"><table>
<thead>
<tr>
<th>ノード名</th>
<th>説明</th>
</tr>
</thead>
<tbody>
<tr>
<td>Zero</td>
<td>Dgraph Zero controls the Dgraph cluster, assigns servers to a group, and re-balances data between server groups.</td>
</tr>
<tr>
<td>Alpha</td>
<td>Dgraph Alpha hosts predicates and indexes.</td>
</tr>
<tr>
<td>Ratel</td>
<td>Ratel serves the UI to run queries, mutations & altering schema.</td>
</tr>
</tbody>
</table></div>
<p>ついでにpredicateとindexの説明.</p>
<div class="table-responsive"><table>
<thead>
<tr>
<th>用語</th>
<th>説明</th>
</tr>
</thead>
<tbody>
<tr>
<td>Predicate</td>
<td>Predicates are either the properties associated with a node or the relationship between two nodes.</td>
</tr>
<tr>
<td>Index</td>
<td>Indexes are the tokenizers that can be associated with the predicates to enable filtering using appropriate functions.</td>
</tr>
</tbody>
</table></div>
<p><a target="_blank" rel="nofollow noopener" href="https://dgraph.io/docs/get-started/">Get Started - Quickstart Guide</a>から引用</p>
<p>少し補足するとPredicateとはノードのプロパティやノードを繋ぐエッジのことです. Indexは他のデータベースと大体同じ意味で索引付けのことで検索するときに指定します.</p>
<h2 id="Dgraphコンテナ"><a href="#Dgraph%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A">Dgraphコンテナ</a></h2>
<p>とりあえずお試しで動かすならdgraph/standaloneというイメージを使います.</p>
<pre><code>docker pull dgraph/standalone:v20.03.0
</code></pre>
<p>起動は以下のようにします.</p>
<pre><code>docker run --name first-dgraph --rm -it -p 8080:8080 -p 9080:9080 -p 8000:8000 -v my-vol:/dgraph dgraph/standalone:v20.03.0
</code></pre>
<p>とりあえ</p>
<div class="table-responsive"><table>
<thead>
<tr>
<th>オプション</th>
<th>説明</th>
</tr>
</thead>
<tbody>
<tr>
<td>name</td>
<td>実行されるコンテナのインスタンスに付けられる名前です</td>
</tr>
<tr>
<td>rm</td>
<td>停止するときにコンテナが削除されます</td>
</tr>
<tr>
<td>it</td>
<td>interactive ttyでttyを通じてコンテナとやり取りできます. 今回はひたすらログが流れてきます.</td>
</tr>
<tr>
<td>0</td>
<td>ポート・フォーワーディングといってホストとクライアントの間でポートの対応を付けを行います</td>
</tr>
<tr>
<td>v</td>
<td>ボリュームをマウントします. my-volはdockerが管理するボリュームで/dgraphがコンテナ側のマウントポイントです</td>
</tr>
</tbody>
</table></div>
<p><strong>注意点はボリュームのマウント・ポイントは/dgraphに指定する必要があります</strong>. しないとrmオプションの効果でコンテナを停止するとデータごと消えてしまいます(お試しだから良いのかもしれませんが).</p>
<p>実行後以下のコマンドでmy-volボリュームが作られていることを確認しましょう.</p>
<pre><code>docker volume ls
</code></pre>
<h2 id="Ratel UIを使ったSchema編集"><a href="#Ratel+UI%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9FSchema%E7%B7%A8%E9%9B%86">Ratel UIを使ったSchema編集</a></h2>
<h3 id="Ratel UIへのアクセス"><a href="#Ratel+UI%E3%81%B8%E3%81%AE%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9">Ratel UIへのアクセス</a></h3>
<p><a target="_blank" rel="nofollow noopener" href="http://localhost:8000/">http://localhost:8000/</a>にアクセスします.</p>
<p><a href="https://crieit.now.sh/upload_images/ebfc02a9cdb0f0fbd51e9d5690617e895f7c3fdde691d.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/ebfc02a9cdb0f0fbd51e9d5690617e895f7c3fdde691d.png?mw=700" alt="image" /></a></p>
<p>真ん中のLatestを選びます.</p>
<p><a href="https://crieit.now.sh/upload_images/c3c3e6a02d081d6906e6811d15b4908c5f7c407a37d6d.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/c3c3e6a02d081d6906e6811d15b4908c5f7c407a37d6d.png?mw=700" alt="image" /></a></p>
<p>スキーマの設定やデータの投入, クエリなどを実行できます.</p>
<h3 id="スキーマを設定する"><a href="#%E3%82%B9%E3%82%AD%E3%83%BC%E3%83%9E%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B">スキーマを設定する</a></h3>
<p>スキーマの設定方法は2つあります.</p>
<ol>
<li>データを投入する</li>
<li>手動でスキーマを定義する</li>
</ol>
<p>基本的にノードを投入すると自動的にスキーマが定義されます. そのため一度スキーマを定義しても新しいプレディケートがあると勝手にスキーマが更新されます.</p>
<p>例えばConsoleのMutationタブに以下をコピペします.</p>
<pre><code class="json">{
"set":[
{
"name": "Michael",
"age": 40
}
]
}
</code></pre>
<p>Runをクリックするとスキーマが生成されます. 左のSchemaタブを選ぶとプレディケートとタイプが表示されます.</p>
<p><a href="https://crieit.now.sh/upload_images/cd364e29ba8e3259a32cc95f47e3e1055f7c4a70039b5.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/cd364e29ba8e3259a32cc95f47e3e1055f7c4a70039b5.png?mw=700" alt="image" /></a></p>
<p>次にアドレスというプレディケートを加えて新しいデータを投入します.</p>
<pre><code class="json">{
"set":[
{
"name": "Michael",
"age": 40,
"e-mail" : "example.com"
}
]
}
</code></pre>
<p>するとe-mailというプレディケートが追加されました.</p>
<p><a href="https://crieit.now.sh/upload_images/1ed70e814b5fa7fa8aaf66607ceb8e465f7c4b2a2950e.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/1ed70e814b5fa7fa8aaf66607ceb8e465f7c4b2a2950e.png?mw=700" alt="image" /></a></p>
<p>このため導入するデータのバリデーションはアプリケーション側で行うのが良さそうです.</p>
<h3 id="スキーマを設定する利点"><a href="#%E3%82%B9%E3%82%AD%E3%83%BC%E3%83%9E%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B%E5%88%A9%E7%82%B9">スキーマを設定する利点</a></h3>
<p>ではスキーマが無駄なのかというと, そうでもないようです. Ratel UIでQueryを入力する際に補完されるようになるようです. ただ階層とかは考慮してくれないようです.</p>
<p><a href="https://crieit.now.sh/upload_images/e58e165c855af120703f0f035bd86f8c5f8062ae7e0ca.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/e58e165c855af120703f0f035bd86f8c5f8062ae7e0ca.png?mw=700" alt="image" /></a></p>
<h2 id="補足"><a href="#%E8%A3%9C%E8%B6%B3">補足</a></h2>
<h3 id="Dockerのボリューム"><a href="#Docker%E3%81%AE%E3%83%9C%E3%83%AA%E3%83%A5%E3%83%BC%E3%83%A0">Dockerのボリューム</a></h3>
<p>ボリュームにはもう一つマウント・ボリュームというのがあります. こちらもホスト側のフォルダをコンテナ側にマウントする点は同じですが, フォルダを自分で指定する必要があります. DockerはWindows, macOS, そして各Linuxディストリビューションで提供されマルティ・プラットフォームでコンテナを動かすことができます. しかしこのマウント・ポイントを指定してしまうと互換性がなくなってしまう可能性があります. そこで後からDocker側がボリュームを管理するような仕組みが導入されたようです. 領域はDockerの管理下にあるので, プラットフォームごとの際はDockerが吸収してくれます.</p>
<pre><code>docker volume create my-vol
</code></pre>
<p>などで作ることができます. 例えばデータの投入は以下のようにします.</p>
<h2 id="Reference"><a href="#Reference">Reference</a></h2>
<p><a target="_blank" rel="nofollow noopener" href="https://discuss.dgraph.io/t/drop-all-data-from-dgraph/5866/2">Drop all data from Dgraph</a></p>
ブレイン