diff --git a/.github/workflows/github-pages.yml b/.github/workflows/github-pages.yml
new file mode 100644
index 0000000..0240050
--- /dev/null
+++ b/.github/workflows/github-pages.yml
@@ -0,0 +1,25 @@
+name: github-pages
+on:
+ push:
+ branches: [main]
+jobs:
+ main:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - uses: actions/setup-node@v2
+ with: { node-version: lts/*, cache: yarn }
+ - name: Git config
+ run: |
+ git config user.name bot
+ git config user.email bot@example
+ - run: git subtree add --prefix book origin gh-pages
+ - run: brew bundle
+ - run: yarn
+ - run: yarn build
+ - name: Publish
+ run: |
+ git add -f book
+ if git commit -m update; then
+ git subtree push --prefix book origin gh-pages
+ fi
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..896eb57
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+/node_modules/
+/book/
+/theme/
diff --git a/.prettierrc.yml b/.prettierrc.yml
new file mode 100644
index 0000000..4ec7f8d
--- /dev/null
+++ b/.prettierrc.yml
@@ -0,0 +1,4 @@
+overrides:
+ - files: "*.md"
+ options:
+ parser: markdown-nocjsp
diff --git a/Brewfile b/Brewfile
new file mode 100644
index 0000000..e74f46d
--- /dev/null
+++ b/Brewfile
@@ -0,0 +1 @@
+brew "mdbook"
diff --git a/Brewfile.lock.json b/Brewfile.lock.json
new file mode 100644
index 0000000..6c7a37a
--- /dev/null
+++ b/Brewfile.lock.json
@@ -0,0 +1,50 @@
+{
+ "entries": {
+ "brew": {
+ "mdbook": {
+ "version": "0.4.10",
+ "bottle": {
+ "rebuild": 0,
+ "root_url": "https://ghcr.io/v2/linuxbrew/core",
+ "files": {
+ "arm64_big_sur": {
+ "cellar": ":any_skip_relocation",
+ "url": "https://ghcr.io/v2/linuxbrew/core/mdbook/blobs/sha256:554151ca6d1771fbbb6dc2dad3d27dfa40629680ad6511690c90596445800ba1",
+ "sha256": "554151ca6d1771fbbb6dc2dad3d27dfa40629680ad6511690c90596445800ba1"
+ },
+ "big_sur": {
+ "cellar": ":any_skip_relocation",
+ "url": "https://ghcr.io/v2/linuxbrew/core/mdbook/blobs/sha256:76903aca2380189e21bfd257a8ec8b130e069fb03cd4415d46ef1af6a711ce2d",
+ "sha256": "76903aca2380189e21bfd257a8ec8b130e069fb03cd4415d46ef1af6a711ce2d"
+ },
+ "catalina": {
+ "cellar": ":any_skip_relocation",
+ "url": "https://ghcr.io/v2/linuxbrew/core/mdbook/blobs/sha256:59e2e920e318782714f1841abb0375f8f17e151f576db14fa0e9041ac14e26cf",
+ "sha256": "59e2e920e318782714f1841abb0375f8f17e151f576db14fa0e9041ac14e26cf"
+ },
+ "mojave": {
+ "cellar": ":any_skip_relocation",
+ "url": "https://ghcr.io/v2/linuxbrew/core/mdbook/blobs/sha256:2f358d7915c4c9c6131e63debcaeabe3e77bfeedf4ecc41dd01c6db5f0229e2a",
+ "sha256": "2f358d7915c4c9c6131e63debcaeabe3e77bfeedf4ecc41dd01c6db5f0229e2a"
+ },
+ "x86_64_linux": {
+ "cellar": ":any_skip_relocation",
+ "url": "https://ghcr.io/v2/linuxbrew/core/mdbook/blobs/sha256:8747b95ef1401af63cab80c7c3dd8ed2e09acac80f48499d951f430b8562c838",
+ "sha256": "8747b95ef1401af63cab80c7c3dd8ed2e09acac80f48499d951f430b8562c838"
+ }
+ }
+ }
+ }
+ }
+ },
+ "system": {
+ "linux": {
+ "Ubuntu 20.04.2 LTS (focal)": {
+ "HOMEBREW_VERSION": "3.2.2",
+ "HOMEBREW_PREFIX": "/home/linuxbrew/.linuxbrew",
+ "Homebrew/linuxbrew-core": "09bc458ee1de62ff7aa9e8ed31082c7b9e4ba9b4",
+ "GCC": "9.3.0"
+ }
+ }
+ }
+}
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..0e259d4
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,121 @@
+Creative Commons Legal Code
+
+CC0 1.0 Universal
+
+ CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
+ LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
+ ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
+ INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
+ REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
+ PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
+ THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
+ HEREUNDER.
+
+Statement of Purpose
+
+The laws of most jurisdictions throughout the world automatically confer
+exclusive Copyright and Related Rights (defined below) upon the creator
+and subsequent owner(s) (each and all, an "owner") of an original work of
+authorship and/or a database (each, a "Work").
+
+Certain owners wish to permanently relinquish those rights to a Work for
+the purpose of contributing to a commons of creative, cultural and
+scientific works ("Commons") that the public can reliably and without fear
+of later claims of infringement build upon, modify, incorporate in other
+works, reuse and redistribute as freely as possible in any form whatsoever
+and for any purposes, including without limitation commercial purposes.
+These owners may contribute to the Commons to promote the ideal of a free
+culture and the further production of creative, cultural and scientific
+works, or to gain reputation or greater distribution for their Work in
+part through the use and efforts of others.
+
+For these and/or other purposes and motivations, and without any
+expectation of additional consideration or compensation, the person
+associating CC0 with a Work (the "Affirmer"), to the extent that he or she
+is an owner of Copyright and Related Rights in the Work, voluntarily
+elects to apply CC0 to the Work and publicly distribute the Work under its
+terms, with knowledge of his or her Copyright and Related Rights in the
+Work and the meaning and intended legal effect of CC0 on those rights.
+
+1. Copyright and Related Rights. A Work made available under CC0 may be
+protected by copyright and related or neighboring rights ("Copyright and
+Related Rights"). Copyright and Related Rights include, but are not
+limited to, the following:
+
+ i. the right to reproduce, adapt, distribute, perform, display,
+ communicate, and translate a Work;
+ ii. moral rights retained by the original author(s) and/or performer(s);
+iii. publicity and privacy rights pertaining to a person's image or
+ likeness depicted in a Work;
+ iv. rights protecting against unfair competition in regards to a Work,
+ subject to the limitations in paragraph 4(a), below;
+ v. rights protecting the extraction, dissemination, use and reuse of data
+ in a Work;
+ vi. database rights (such as those arising under Directive 96/9/EC of the
+ European Parliament and of the Council of 11 March 1996 on the legal
+ protection of databases, and under any national implementation
+ thereof, including any amended or successor version of such
+ directive); and
+vii. other similar, equivalent or corresponding rights throughout the
+ world based on applicable law or treaty, and any national
+ implementations thereof.
+
+2. Waiver. To the greatest extent permitted by, but not in contravention
+of, applicable law, Affirmer hereby overtly, fully, permanently,
+irrevocably and unconditionally waives, abandons, and surrenders all of
+Affirmer's Copyright and Related Rights and associated claims and causes
+of action, whether now known or unknown (including existing as well as
+future claims and causes of action), in the Work (i) in all territories
+worldwide, (ii) for the maximum duration provided by applicable law or
+treaty (including future time extensions), (iii) in any current or future
+medium and for any number of copies, and (iv) for any purpose whatsoever,
+including without limitation commercial, advertising or promotional
+purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
+member of the public at large and to the detriment of Affirmer's heirs and
+successors, fully intending that such Waiver shall not be subject to
+revocation, rescission, cancellation, termination, or any other legal or
+equitable action to disrupt the quiet enjoyment of the Work by the public
+as contemplated by Affirmer's express Statement of Purpose.
+
+3. Public License Fallback. Should any part of the Waiver for any reason
+be judged legally invalid or ineffective under applicable law, then the
+Waiver shall be preserved to the maximum extent permitted taking into
+account Affirmer's express Statement of Purpose. In addition, to the
+extent the Waiver is so judged Affirmer hereby grants to each affected
+person a royalty-free, non transferable, non sublicensable, non exclusive,
+irrevocable and unconditional license to exercise Affirmer's Copyright and
+Related Rights in the Work (i) in all territories worldwide, (ii) for the
+maximum duration provided by applicable law or treaty (including future
+time extensions), (iii) in any current or future medium and for any number
+of copies, and (iv) for any purpose whatsoever, including without
+limitation commercial, advertising or promotional purposes (the
+"License"). The License shall be deemed effective as of the date CC0 was
+applied by Affirmer to the Work. Should any part of the License for any
+reason be judged legally invalid or ineffective under applicable law, such
+partial invalidity or ineffectiveness shall not invalidate the remainder
+of the License, and in such case Affirmer hereby affirms that he or she
+will not (i) exercise any of his or her remaining Copyright and Related
+Rights in the Work or (ii) assert any associated claims and causes of
+action with respect to the Work, in either case contrary to Affirmer's
+express Statement of Purpose.
+
+4. Limitations and Disclaimers.
+
+ a. No trademark or patent rights held by Affirmer are waived, abandoned,
+ surrendered, licensed or otherwise affected by this document.
+ b. Affirmer offers the Work as-is and makes no representations or
+ warranties of any kind concerning the Work, express, implied,
+ statutory or otherwise, including without limitation warranties of
+ title, merchantability, fitness for a particular purpose, non
+ infringement, or the absence of latent or other defects, accuracy, or
+ the present or absence of errors, whether or not discoverable, all to
+ the greatest extent permissible under applicable law.
+ c. Affirmer disclaims responsibility for clearing rights of other persons
+ that may apply to the Work or any use thereof, including without
+ limitation any person's Copyright and Related Rights in the Work.
+ Further, Affirmer disclaims responsibility for obtaining any necessary
+ consents, permissions or other rights required for any use of the
+ Work.
+ d. Affirmer understands and acknowledges that Creative Commons is not a
+ party to this document and has no duty or obligation with respect to
+ this CC0 or use of the Work.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..b93568a
--- /dev/null
+++ b/README.md
@@ -0,0 +1,17 @@
+# Hasuraで作るREST API
+
+## ローカル環境でのビルド
+
+### 前提
+
+- Ubuntu 20.04 LTS
+- Homebrew
+- Yarn
+
+### 手順
+
+下記のコマンドを実行すると `book` ディレクトリ以下にファイルが生成されます。
+
+```sh
+brew bundle && yarn && yarn build
+```
diff --git a/book.toml b/book.toml
new file mode 100644
index 0000000..c15c5bc
--- /dev/null
+++ b/book.toml
@@ -0,0 +1,10 @@
+[book]
+language = "ja"
+title = "Hasuraで作るREST API"
+authors = ["Kohei Watanabe"]
+src = "docs"
+
+[output.html]
+site-url = "/hasura-rest-hands-on/"
+git-repository-url = "https://github.com/kou029w/hasura-rest-hands-on"
+edit-url-template = "https://github.com/kou029w/hasura-rest-hands-on/edit/main/{path}"
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 0000000..7059c41
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,8 @@
+# Hasuraで作るREST API
+
+Hasuraを使用してPostgresデータベースに接続したREST APIを構築します。
+
+
diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md
new file mode 100644
index 0000000..6e889fa
--- /dev/null
+++ b/docs/SUMMARY.md
@@ -0,0 +1,13 @@
+# 目次
+
+- [Hasuraで作るREST API](README.md)
+- [事前準備](preparation.md)
+ - [Herokuのアカウント登録](signup-heroku.md)
+ - [Hasura Cloudのアカウント登録](signup-hasura-cloud.md)
+- [Hasura Cloudプロジェクトの作成](create-project.md)
+- [Heroku Databaseへの接続](create-heroku-database.md)
+- [テーブルの作成](create-table.md)
+- [GraphQLによるデータの挿入と取得](insert-and-select.md)
+- [REST APIエンドポイントの作成](create-rest-endpoint.md)
+- [アクセス権の設定](permissions.md)
+- [Vueアプリケーションの作成](create-vue-app.md)
diff --git a/docs/create-heroku-database.md b/docs/create-heroku-database.md
new file mode 100644
index 0000000..1a528db
--- /dev/null
+++ b/docs/create-heroku-database.md
@@ -0,0 +1,11 @@
+# Heroku Databaseへの接続
+
+![](https://lh3.googleusercontent.com/ekEWHMTkf2qak5oItkay-scmzeiwiaUtNXBvBdCSVSJ3qG25oVc8O_25S4SEWZskj6NqWSfW2eENeEy3iJ94mTw1SmhnL7tONbS_qHHZsgI4l_6sEIdmMnXTEpmF34-aDS2I3Pi7EQ=w1280)
+
+![](https://lh3.googleusercontent.com/46sywF2Hl5GGAEsXhAkhhni4_NHcB-kcHiqqJNkZs0HS7zvFy9FZmmWEGLtP-i6F-msLnuJlKPFst8j8_QTCnTcDi1B5diKByqOVDAeuZ_PL1Fo_pDl_DLOBscL-O8ucqZA05_xyjA=w1280)
+
+![](https://lh3.googleusercontent.com/RngvddZ704jKqqPfxGiSEdEkBemMwrz3jApRJQhRqL2Cr0MoV-SxVljdLaglM0XFwkcnIpWFD9zVyUtn9n55LGKG78gJPec6HRrWXrcLbNNnHztycmF-sphYYBkHaRT7Y87nzihdNg=w1280)
+
+![](https://lh3.googleusercontent.com/-0FkvEXZO0FQz0YvrNFdh8JmAMZPbIpaIRygkE4F8xb4Z3ZLMRH9y5pny48-bj-i2nnhbDuqcPKokbznD7X_APL-MkjDeHaxQsJjFyGEY6AxvMBsHwfNOjxPdjQA6S3dGrW1Cz4o0g=w1280)
+
+![](https://lh3.googleusercontent.com/vJU-gDZJwSNJYAaoq4qu4lAnxhNYGE70rPxmtGct_GyPT9oH0FoZ8_2O8bcI9ocaWHaJsE0Rqv2WHZzO6Z0yGuMkaCtMYjdIKTHW2aREaCYid73GlT6FWLZH9JIQPp_P9QOez0EOBw=w1280)
diff --git a/docs/create-project.md b/docs/create-project.md
new file mode 100644
index 0000000..b328629
--- /dev/null
+++ b/docs/create-project.md
@@ -0,0 +1,12 @@
+# Hasura Cloudプロジェクトの作成
+
+もし、プロジェクトが存在しない場合、まずプロジェクトの作成を行います。
+すでに存在するプロジェクトを利用する場合は不要です。
+
+![](https://lh3.googleusercontent.com/S5JmjK-PKTK1BW7Q0CXxQWfLpy4T8j96n3QqKy9p88fsLXPDX056uR3bC4MlhBJcSUjcSWNoJrc9mkXq3PG4S-Aax55awJrP65MSx6_dpavy0tNEsAE4YGu3X0IImUjYdE_7QesTHA=w1280)
+
+![](https://lh3.googleusercontent.com/OHk3SnMo5zFoulppRwCkAahq6wr4JImN88XgSlkHYeZFhPTd1pHQp4CUXmDDRTAdmsk9kNCJLLzZ0x_yCH1kcnLQ9Zbkq2lm5KIJblFDBU56nJ3sSdposGBFVyUwrEMBXgNmox297A=w1280)
+
+![](https://lh3.googleusercontent.com/LL6dz4np-O19_runPMbCD5-d3kYc1_QUcc1bJif4Yx7dNr16SY4k6037kV82aqg1FrcYff3QGOFTqzyh9ReYyp-j43EtGJercr7dKxdBxcd1nDzPm9bbWFgJOYjhwNDUsGRWNV2d2g=w1280)
+
+画面上にプロジェクトが表示されれば完了です。
diff --git a/docs/create-rest-endpoint.md b/docs/create-rest-endpoint.md
new file mode 100644
index 0000000..94bd0a1
--- /dev/null
+++ b/docs/create-rest-endpoint.md
@@ -0,0 +1,36 @@
+# REST APIエンドポイントの作成
+
+![](https://lh3.googleusercontent.com/WpWX9e0zMECBpUvdyFXyPAxKauwgpNVAwGSLzjt3M99aeL9t90CrqZrdpEf39uh5SKPBeYvfMX0i6KvTuXf39_rccK1o7aohwFL_OCmz0TX-i0Lc2tlJpk5gPMdTrEqzKyElKvPzEQ=w1280)
+
+get page
+GET page/:id
+
+```graphql
+query getPage($id: Int!) {
+ page: pages_by_pk(id: $id) {
+ id
+ content
+ }
+}
+```
+
+![](https://lh3.googleusercontent.com/fKkiNL4nWYUtiG8OfAk8mhTxdJuZQclLLBWheVclr4EcC7ggsZzpI4mTYGQ-6pvWZWApa2acaUJKVjOFy5oHwqhtVfn4arYX01B29yUvOQwWPRIq-6JOBFNTfP_FxoNJNRaseYEMbw=w1280)
+
+![](https://lh3.googleusercontent.com/yeEU1sF7DR3VA7tWn-FDofpFIfK93q2hssqnn25c_-0bnAbo8WdzdTahQ3HVst7hCniT5hJqHgWS9Pu9zTQorHxErtdp8PSFJmgsU6R0G_oPzF__Up-aSdHQWFc_uuWyVU_Ux50jlw=w1280)
+
+put page
+PUT page/:id
+
+```graphql
+mutation putPage($id: Int!, $content: jsonb!) {
+ page: insert_pages_one(
+ object: { id: $id, content: $content }
+ on_conflict: { constraint: pages_pkey, update_columns: content }
+ ) {
+ id
+ content
+ }
+}
+```
+
+![](https://lh3.googleusercontent.com/NUKkifFtbdjjti9tga3fHp0-iIc4e48Cz2HrBOUngbaDad5an29hJ9ucn7kG3MXLIyZw80wpfG3aZZrS9kDEYUnl9cV3VB0oZ6LqIRKbHlgUGBF2PJJC9ifLCABZhmn1Rv8u9mZ8qw=w1280)
diff --git a/docs/create-table.md b/docs/create-table.md
new file mode 100644
index 0000000..d0fbd57
--- /dev/null
+++ b/docs/create-table.md
@@ -0,0 +1,12 @@
+# テーブルの作成
+
+![](https://lh3.googleusercontent.com/nZo9b7TW32khyJBmmxzrk8GZfqWsPSfmPYdNAyIJ_L3tCek0p8zZl6JCCB7zXvmUbFHtnk2LYnzAimbImFC_ZS0aekik4MUr6jkX9wQTAaLCYXit8k1HgAw9aDvCmcGSl7WM_Ue7Rg=w1280)
+
+
+
+![](https://lh3.googleusercontent.com/L8V_vs7cCKWrzUlnh9H78aDCgPYjFaLxiZNN76lte8zU3NR9x1-jEy91Hx5hpulA4EfCcdPww7dbBqhzBXUBku6HdGKUvPm_4JZFmZSlX9Xy2mmjCRsyktfZuivCr98CdP-pfJX2uQ=w1280)
diff --git a/docs/create-vue-app.md b/docs/create-vue-app.md
new file mode 100644
index 0000000..2cf44b5
--- /dev/null
+++ b/docs/create-vue-app.md
@@ -0,0 +1,47 @@
+# Vueアプリケーションの作成
+
+https://qfmmc.csb.app/
+
+```vue
+
+
+
+
+
+```
+
+![](https://lh3.googleusercontent.com/Z6UJraog11NnBg8lhyrAcdWRhfTEjTbOMv2kRLGTDzJF-d28Bn4MN7W-kymVztsbMa5SGXx8qS-NQoKF9o_pu2UlI9FJyS4AljIEOcJMULEsic-jk5TbOHtBF0eCerbGaQAcxb45qw=w1280)
+
+![](https://lh3.googleusercontent.com/WYpxLUGM52BZ0m5cQ_ZsEjfljdwLbaFkN47XTKp0Z9BPsDPhVImcR3rt9oWop-59ABCF2ubfsQOw2yyZAoT1GIkcjnZ4DCReg5Qn22pyOVT6DblipYIg3S0OZekcCziKxX9Fc6x_BA=w1280)
+
+![](https://lh3.googleusercontent.com/twteosRUkmMlBoa8PXU3UXC9umek-TzQ1kwOWZIShW7fKvW_4tVtG7B3Ue-olldhxh05x1JTFtt_Oxn2nLxcDPEGBv32bkE2zjpqL7heEjV54jkDgYqOm1tEq02qvnKoqu5yaSKRZA=w800)
diff --git a/docs/insert-and-select.md b/docs/insert-and-select.md
new file mode 100644
index 0000000..0ad20f3
--- /dev/null
+++ b/docs/insert-and-select.md
@@ -0,0 +1,47 @@
+# GraphQLによるデータの挿入と取得
+
+
+
+
+```graphql
+mutation MyMutation {
+ insert_pages_one(object: {content: {}}) {
+ id
+ content
+ }
+}
+```
+
+
+![](https://lh3.googleusercontent.com/ygTdByArh1HC1hmh_Eq76ExXmcy0bq2k2y4uBgS3Gdqs7VPb9SjsjuPa_vB5o55Wt69yswx-UHHbjhLdQLH0Cnd2zLMKIWU8wKpQ_zPXmpKki6H5ugVg8B7qDwfY2qnZthheXM-h9w=w1280)
+
+
+```graphql
+mutation MyMutation {
+ insert_pages_one(object: {content: {hey: "hello!"}}) {
+ id
+ content
+ }
+}
+```
+
+
+![](https://lh3.googleusercontent.com/jJ11PeUPl-HOu38_Om5KSwm0WguYTopL9Gw1SXX7x9RxRfiBfNNp9Su6FtzzEwsQGZNm8HUX76McMs1YfuhnU9tJWgZoJfpma7_Zk8U2SaOgizNV-G4TA4eKIE5yR5cglZai43It2g=w1280)
+
+![](https://lh3.googleusercontent.com/2ExXahoxvOy25dwNkM8YhlVdlo_3T5kjqGDSRzDfV2O3TV3gjK2F03zp_ewSuafsH_nyS0voOsX5G6uahxSgNRp-BpYpQSCFE36v85D_sEaSnfMcGwPnQMI7kWqsV0X1aUAQhnUgqg=w1280)
+
+
+```graphql
+query MyQuery {
+ pages_by_pk(id: 2) {
+ id
+ content
+ }
+}
+```
+
+
+![](https://lh3.googleusercontent.com/WE8Pqbr0M-RwfGTxoq8uPyZcLkjppcP_g5HVGastYV_pr7Q_mYB9svilyeTRF7G0WK7g4Xgi19AgamY-8h9xuo_05AKb5r96dtiJJpWe7IX7aJjCs9fBssMxhAZUfDA1OsJ1NZ_Yvw=w1280)
diff --git a/docs/permissions.md b/docs/permissions.md
new file mode 100644
index 0000000..b201770
--- /dev/null
+++ b/docs/permissions.md
@@ -0,0 +1,17 @@
+# アクセス権の設定
+
+![](https://lh3.googleusercontent.com/Uq0iRyw6DlL5jbIMpL9xEpC-4tX1S-RZSIyFM4uCbTQAXD6nWy8l7Y7QLv0Akq4dKKzD88Tyn1rZfW7bDSI2Y_RRV55upoQBIPmvwvvsK-vo8A9q4y1Ys5Zw9dEmU366_uxRr-hBrg=w1280)
+
+![](https://lh3.googleusercontent.com/IqvuzDGhNd8qYoFVlmJxjbP2iUQnz1V93jk4fGOv62QjJMpvMRS5LGOpaCoiJljIDdNqLqCII3J8b4yXx2IuAzAe0EBK9BkGaMq4MYn_NPOe2naCF9T_Vhz5csmH8dPDDCFQNDBnMw=w1280)
+
+![](https://lh3.googleusercontent.com/ZbyxyVmmbqOtKD5sJsCeD_iG8v5qP_iYbFHM6PDfsFTNtdVmAfkXd9kzB8i_ZMLqDVbJguI0GS1aHmSj_7kgL3x-AyPth6x0WhEQQyb5JWgiU2sAzRAL_rjXNIkWQLHYn1T8p1o_Mg=w1280)
+
+![](https://lh3.googleusercontent.com/kD9ZrdOSbLuWZ-i8Z_e9NyHcNX3y05RaC3Wf9TQv80TY7kWctQ0yrpPF2Xj1tx4nKrRgLNwzYsMc9zjQEh5MiqNHvXOQGipQ6L0NkVU-S8KmDM7zdJM78ZxeEfG52bWza32HYux47g=w1280)
+
+![](https://lh3.googleusercontent.com/GxpRsX2PER72FUWX-xQRF5pjGwHa0fydneULevgxMNqJfK4-z62D1ig7qKnRgijB37zAoKmCMlCd3ZvqXJqhoXwGXkYK30pB2a93YeOdIWELjjPqMla9OKRpMC99LN3tqosd_CpcuQ=w1280)
+
+![](https://lh3.googleusercontent.com/egQYbjJjs_0kLlCmPpHe93odORHapxeZn-aEleKKFq2kPEtODMUd_j65aHPftyBZ_sMz9Ypy6P55fIk0KrIl1UC-mbL6zerBj7uYB0c0MofDz2I7sKC066oHsTN4BEjjxFz1fo54gA=w1280)
+
+![](https://lh3.googleusercontent.com/TZHIQuC6MviESxMktg2GYuS7yLJXrJCnhrGmVlB60EFaUpPalW6rVfHo01x5lWPvWwu047JLFSnCK22LDxL1m1fSH_OKzAopA9aV6sHGdLRSLUEOBS7i-cUBlR0TQvsIQG27Ky8obA=w1280)
+
+![](https://lh3.googleusercontent.com/C1hwqyYYH8jtAZfkJG5y6DlOn7mYn9cXI1Er5xnGKZcddVw7dP_yj8_-j7v9D-SOjOi0Pu1qM74fLRu9XjSjFkU6LWbNysgS7QVU1ROqVJf0Ic0Hwud4rZyoxhopks2G8veA9SIMWg=w1280)
diff --git a/docs/preparation.md b/docs/preparation.md
new file mode 100644
index 0000000..d8a944b
--- /dev/null
+++ b/docs/preparation.md
@@ -0,0 +1,6 @@
+# 事前準備
+
+あらかじめ下記のアカウントに登録しておきましょう。
+
+- [Herokuのアカウント登録](signup-heroku.md)
+- [Hasura Cloudのアカウント登録](signup-hasura-cloud.md)
diff --git a/docs/signup-hasura-cloud.md b/docs/signup-hasura-cloud.md
new file mode 100644
index 0000000..7a5953c
--- /dev/null
+++ b/docs/signup-hasura-cloud.md
@@ -0,0 +1,31 @@
+# Hasura Cloudのアカウント登録
+
+[Signup - Hasura Cloud](https://cloud.hasura.io/signup)
+
+または
+
+[![Deploy to Hasura](https://graphql-engine-cdn.hasura.io/assets/main-site/deploy-hasura-cloud.png)](https://cloud.hasura.io/)
+
+このリンクから、Hasura Cloudにアクセスします。
+
+![](https://lh3.googleusercontent.com/7MK3GMXczQ-nuDgAHVj33BnyI5tE_uLwMQaiaM_N5jc3MFSMMZJlPT-ucYMYPVhbb4IU17eeK6djxU3WFLVpdlkbq-J8oxNQD872Zh2tzNsOrf0jSxopfFmFmNtE3UsixFLTEr-QJg=w1280)
+
+GitHubアカウントまたはGoogleアカウント、メールアドレスを使って登録が可能です。
+
+GitHubアカウントを使用する場合:
+
+事前に[Join GitHub](https://github.com/join)からGitHubアカウントを作成し、サインインします。
+
+Googleアカウントを使用する場合:
+
+事前に[Google アカウントの作成](https://accounts.google.com/signup)し、ログインします。
+
+メールアドレスを使用する場合:
+
+[Signup - Hasura Cloud](https://cloud.hasura.io/signup) > [Sign up with Email] から、必要事項を入力し、アカウントを登録します。
+
+![](https://lh3.googleusercontent.com/MwmAaaH9eoLQpq6Io8zxzLS5UuxiDsqi1DOyqMHEh_qw7h81z2CTovf5GDz-rdCZEe2qL9uo-Xodx-lCsHuf_b5ZkivKUuREvB-QRGOZX3xY-eGwME4SclPLCwnXjTGbkSnRAAmX9g=w1280)
+
+アカウントを作成後、[Hasura Cloudのプロジェクト一覧](https://cloud.hasura.io/projects)にアクセスできれば完了です。
+
+![](https://lh3.googleusercontent.com/YkXj40BFxZIEYUOxvshu6uhOWQcsgoh9UfQDUlEJ2FMf-sCqNuiEoRWkDsZdDrmXSFAUAnxIlZgQBt8bgebXYhWXTPS_RE7yjMg4a_h-CbimnD3gS4vnK6EpM-s1IqK7wPBI4BAScg=w1280)
diff --git a/docs/signup-heroku.md b/docs/signup-heroku.md
new file mode 100644
index 0000000..3d231fe
--- /dev/null
+++ b/docs/signup-heroku.md
@@ -0,0 +1,19 @@
+# Herokuのアカウント登録
+
+[Herokuの新規登録](https://signup.heroku.com/jp)からアカウントを作成します。
+
+アカウントに必要な項目を入力します。
+
+![](https://lh3.googleusercontent.com/Wa1OrwezKqGADEq-TC1ErAMWRKfrKxr1FWqLXuwPyn2GiKQlIbvmA6tCbsPGA0NWwEwKePo2_574LPl7fdwX89mDE8gltPCBRPFQ24GSdpI4tXQsDU5mfk1o1oqMWrmZPxCOJkm64g=w1280)
+
+入力したメールアドレスに登録用のメールが届くので確認します。
+
+![](https://lh3.googleusercontent.com/c4IrmzaCjk-SuJ4w9t_7esDEdOT1CGj7gLcWPBZxswSbbmvGyOgPz2rUzPlpkyGqGncId9bMHqDl0hya99s3QbEuWbi9CFMpP04A9Vi8txzdzhNpJxI0o2nxEY9SIcIWVmc1Ncqjrw=w1280)
+
+メールに記載のリンクにアクセスし、パスワードを設定します。
+
+![](https://lh3.googleusercontent.com/oGniSBYOCGH3Zb56034x_tzQTGWuZF_81PkEEX68Xk5TCHYs_LmyyS0uZAgkBr5RHdZZVSpbxsZWlgyXeqfEp5NTFb4Ry3EV4I-Wxp07TK-9kpvmtuWLYddkJx4mPmEfuj283RZtJA=w1280)
+
+Herokuにようこそ!
+
+![](https://lh3.googleusercontent.com/klQnC0-tt3v_lcSGRSa_S6L1PvOxLl_e-BGhL75Lmi0Tei-zqJMtvab1GfcdhuwNqUcOqPjvsWUtzQLNMK_cGSrznFmLtFemCLfUnAQRHoKqdvpIsyshwDi7plwfGHM1y8R0gTyy-Q=w1280)
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..be1d990
--- /dev/null
+++ b/package.json
@@ -0,0 +1,15 @@
+{
+ "name": "@kou029w/hasura-rest-hands-on",
+ "version": "1.0.0",
+ "private": true,
+ "scripts": {
+ "build": "esbuild src/*.js --outdir=theme --platform=browser --bundle --minify && mdbook build"
+ },
+ "devDependencies": {
+ "esbuild": "^0.12.15",
+ "highlight.js": "^11.1.0",
+ "highlightjs-graphql": "^1.0.2",
+ "prettier": "^2.3.2",
+ "prettier-plugin-md-nocjsp": "^1.1.1"
+ }
+}
diff --git a/src/highlight.js b/src/highlight.js
new file mode 100644
index 0000000..0d4a98b
--- /dev/null
+++ b/src/highlight.js
@@ -0,0 +1,21 @@
+/**
+ * @license
+ * highlight.js
+ * License: BSD-3-Clause
+ * Copyright (c) 2006 Ivan Sagalaev
+ */
+import hljs from "highlight.js";
+import vue from "highlight.js/lib/languages/xml";
+
+/**
+ * @license
+ * highlightjs-graphql
+ * License: MIT
+ * Copyright (c) 2019 David Peek
+ */
+import { definer as graphql } from "highlightjs-graphql";
+
+Object.entries({ vue, graphql }).forEach((language) => {
+ hljs.registerLanguage(...language);
+});
+Object.assign(window, { hljs });
diff --git a/yarn.lock b/yarn.lock
new file mode 100644
index 0000000..7e65ac2
--- /dev/null
+++ b/yarn.lock
@@ -0,0 +1,28 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+esbuild@^0.12.15:
+ version "0.12.15"
+ resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.12.15.tgz#9d99cf39aeb2188265c5983e983e236829f08af0"
+ integrity sha512-72V4JNd2+48eOVCXx49xoSWHgC3/cCy96e7mbXKY+WOWghN00cCmlGnwVLRhRHorvv0dgCyuMYBZlM2xDM5OQw==
+
+highlight.js@^11.1.0:
+ version "11.1.0"
+ resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.1.0.tgz#0198f7326e64ddfbea5f76b00e84ab542cf24ae8"
+ integrity sha512-X9VVhYKHQPPuwffO8jk4bP/FVj+ibNCy3HxZZNDXFtJrq4O5FdcdCDRIkDis5MiMnjh7UwEdHgRZJcHFYdzDdA==
+
+highlightjs-graphql@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/highlightjs-graphql/-/highlightjs-graphql-1.0.2.tgz#841e26831e7da9f0a3d66f93e6ff98a0d1ad6f43"
+ integrity sha512-jShTftpKQDwMXc+7OHOpHXRYSweT08EO2YOIcLbwU00e9yuwJMYXGLF1eiDO0aUPeQU4/5EjAh5HtPt3ly7rvg==
+
+prettier-plugin-md-nocjsp@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/prettier-plugin-md-nocjsp/-/prettier-plugin-md-nocjsp-1.1.1.tgz#c0f9b00eee636d34ad736d6bf01600a794146be4"
+ integrity sha512-KeymD5eu5FrlgGxwt+U27RipSG4SItn5ZqfPFutgmiVLO1clKHtPylRWSf6DnkfnjgUEytEtB4FPOdj1YK2bww==
+
+prettier@^2.3.2:
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.2.tgz#ef280a05ec253712e486233db5c6f23441e7342d"
+ integrity sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==