From 30fbc0bc9af9a44988fdd3f3e0fe36de9b3bb99c Mon Sep 17 00:00:00 2001 From: cocodrips Date: Wed, 23 Aug 2023 17:23:31 +0900 Subject: [PATCH] Copy from 2023 --- README.md | 25 ++--- data/workflow-enable.png | Bin 0 -> 18324 bytes document/{step1.en.md => 01-git.en.md} | 27 +++--- document/{step1.ja.md => 01-git.ja.md} | 23 +++-- document/{step2.en.md => 02-local-env.en.md} | 12 ++- document/{step2.ja.md => 02-local-env.ja.md} | 10 +- document/{step3.en.md => 03-api.en.md} | 81 ++-------------- document/{step3.ja.md => 03-api.ja.md} | 90 +++--------------- document/04-database.en.md | 68 +++++++++++++ document/04-database.ja.md | 81 ++++++++++++++++ document/{step4.en.md => 05-docker.en.md} | 17 ++-- document/{step4.ja.md => 05-docker.ja.md} | 20 ++-- document/06-ci.en.md | 43 +++++++++ document/06-ci.ja.md | 41 ++++++++ document/{step5.en.md => 07-frontend.en.md} | 8 +- document/{step5.ja.md => 07-frontend.ja.md} | 4 +- .../{step6.en.md => 08-docker-compose.en.md} | 23 +++-- .../{step6.ja.md => 08-docker-compose.ja.md} | 23 +++-- ...ackathon.en.md => 10-team-hackathon.en.md} | 6 +- ...ackathon.ja.md => 10-team-hackathon.ja.md} | 0 go/dockerfile | 6 +- go/go.mod | 2 +- python/dockerfile | 6 +- typescript/simple-mercari-web/dockerfile | 4 + .../simple-mercari-web/public/index.html | 4 +- .../simple-mercari-web/public/manifest.json | 4 +- .../src/components/ItemList/ItemList.tsx | 2 +- .../src/components/Listing/Listing.tsx | 2 +- 28 files changed, 390 insertions(+), 242 deletions(-) create mode 100644 data/workflow-enable.png rename document/{step1.en.md => 01-git.en.md} (72%) rename document/{step1.ja.md => 01-git.ja.md} (80%) rename document/{step2.en.md => 02-local-env.en.md} (77%) rename document/{step2.ja.md => 02-local-env.ja.md} (83%) rename document/{step3.en.md => 03-api.en.md} (56%) rename document/{step3.ja.md => 03-api.ja.md} (57%) create mode 100644 document/04-database.en.md create mode 100644 document/04-database.ja.md rename document/{step4.en.md => 05-docker.en.md} (82%) rename document/{step4.ja.md => 05-docker.ja.md} (85%) create mode 100644 document/06-ci.en.md create mode 100644 document/06-ci.ja.md rename document/{step5.en.md => 07-frontend.en.md} (93%) rename document/{step5.ja.md => 07-frontend.ja.md} (97%) rename document/{step6.en.md => 08-docker-compose.en.md} (69%) rename document/{step6.ja.md => 08-docker-compose.ja.md} (75%) rename document/{team-hackathon.en.md => 10-team-hackathon.en.md} (89%) rename document/{team-hackathon.ja.md => 10-team-hackathon.ja.md} (100%) diff --git a/README.md b/README.md index 5f70d0483..28fbcf5de 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Build@Mercari Training Program 2022 +# Build@Mercari Training Program 2023 This is @'s build training repository. @@ -23,16 +23,19 @@ The following icons indicate pointers for ## Tasks -- [ ] **STEP1** Git ([JA](document/step1.ja.md)/[EN](document/step1.en.md)) -- [ ] **STEP2** Setup environment ([JA](document/step2.ja.md) - /[EN](document/step2.en.md)) -- [ ] **STEP3** Develop API ([JA](document/step3.ja.md) - /[EN](document/step3.en.md)) -- [ ] **STEP4** Docker ([JA](document/step4.ja.md)/[EN](document/step4.en.md)) -- [ ] **STEP5** (Stretch) Frontend ([JA](document/step5.ja.md) - /[EN](document/step5.en.md)) -- [ ] **STEP6** (Stretch) Run on docker-compose ([JA](document/step6.ja.md) - /[EN](document/step6.en.md)) +- [ ] **STEP1** Git ([JA](document/01-git.ja.md)/[EN](document/01-git.en.md)) +- [ ] **STEP2** Setup environment ([JA](document/02-local-env.ja.md) + /[EN](document/02-local-env.en.md)) +- [ ] **STEP3** Develop API ([JA](document/03-api.ja.md) + /[EN](document/03-api.en.md)) +- [ ] **STEP4** Database ([JA](document/04-database.ja.md)/[EN](document/04-database.en.md)) +- [ ] **STEP5** Docker ([JA](document/05-docker.ja.md)/[EN](document/05-docker.en.md)) +- [ ] **STEP6** Continuous Integration(CI) ([JA](document/06-ci.ja.md) + /[EN](document/06-ci.en.md)) +- [ ] **STEP7** (Stretch) Frontend ([JA](document/07-frontend.ja.md) + /[EN](document/07-frontend.en.md)) +- [ ] **STEP8** (Stretch) Run on docker-compose ([JA](document/08-docker-compose.ja.md) + /[EN](document/08-docker-compose.en.md)) ### Other documents diff --git a/data/workflow-enable.png b/data/workflow-enable.png new file mode 100644 index 0000000000000000000000000000000000000000..ab6e51afd5597ffb0bc4f203b0a52f38e422235b GIT binary patch literal 18324 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/mercari-build-training-2022` if successful. + + +## Fork this **mercari-build-training-2023** repository + +* Fork [mercari-build-training-2023](https://github.com/mercari-build/mercari-build-training-2023) +* You will see be able to see `https://github.com//mercari-build-training-2023` if successful. ## Install Git @@ -30,24 +35,24 @@ In this step, we will learn how to use Git and Github. ## Use basic commands in Git -1. **Clone** `https://github.com//mercari-build-training-2022` onto your local using the following command. +1. **Clone** `https://github.com//mercari-build-training-2023` onto your local using the following command. ```shell $ cd - $ git clone https://github.com//mercari-build-training-2022 + $ git clone https://github.com//mercari-build-training-2023 ``` **:bangbang: Caution** Please definitely run the following command after cloning repository. ``` -cd mercari-build-training-2022 +cd mercari-build-training-2023 git config --local core.hooksPath .githooks/ ``` -This is required to use githooks in mercari-build-training-2022 repository. +This is required to use githooks in mercari-build-training-2023 repository. 2. Make a new branch named `first-pull-request` and **checkout** into this branch ```shell - $ cd /mercari-build-training-2022 + $ cd /mercari-build-training-2023 $ git branch first-pull-request $ git checkout first-pull-request ``` @@ -90,4 +95,4 @@ Check if you understand the following concepts. ### Next -[STEP2: Building local environmentSTEP2: Building local environment](step2.en.md) +[STEP2: Building local environment](02-local-env.en.md) diff --git a/document/step1.ja.md b/document/01-git.ja.md similarity index 80% rename from document/step1.ja.md rename to document/01-git.ja.md index f36ac8a14..ba9d953ed 100644 --- a/document/step1.ja.md +++ b/document/01-git.ja.md @@ -3,14 +3,17 @@ このステップではGitとGithubの使い方を学びます。 **:book: Reference** -* [Gitを使ったバージョン管理](https://backlog.com/ja/git-tutorial/intro/01/) -* [Udemy - Git & Github基礎講座](https://www.udemy.com/course/git-github-a/) -## **mercari-build-training-2022** リポジトリをフォークする +* (JA)[Gitを使ったバージョン管理](https://backlog.com/ja/git-tutorial/intro/01/) +* (JA)[Udemy Business - Git:はじめてのGitとGitHub](https://mercari.udemy.com/course/intro_git/) -* [mercari-build-training-2022](https://github.com/mercari-build/mercari-build-training-2022) +* (EN)[Git basics](https://www.atlassian.com/git) +* (EN)[Udemy Business - GitHub Ultimate: Master Git and GitHub - Beginner to Expert](https://mercari.udemy.com/course/github-ultimate/) +## **mercari-build-training-2023** リポジトリをフォークする + +* [mercari-build-training-2023](https://github.com/mercari-build/mercari-build-training-2023) をあなたのGithubにForkします。 -* Forkに成功すると `https://github.com//mercari-build-training-2022` +* Forkに成功すると `https://github.com//mercari-build-training-2023` というようなリポジトリができます。 ## Gitをインストールする @@ -30,25 +33,25 @@ ## Gitの基本コマンドを使う -1. `https://github.com//mercari-build-training-2022` を **clone** +1. `https://github.com//mercari-build-training-2023` を **clone** します。 cloneすると、github上のリポジトリを自分のローカルにDownloadできます。 ```shell $ cd - $ git clone https://github.com//mercari-build-training-2022 + $ git clone https://github.com//mercari-build-training-2023 ``` **:bangbang: 注意** cloneができたら必ず以下のコマンドを実行してください。 ```shell -$ cd mercari-build-training-2022 +$ cd mercari-build-training-2023 $ git config --local core.hooksPath .githooks/ ``` これは mercari-build-training-2022 が githooks という機能を使うために必要なものです。 2. `first-pull-request`というブランチを作り、そのブランチに**checkout**します ```shell - $ cd /mercari-build-training-2022 + $ cd /mercari-build-training-2023 $ git branch first-pull-request $ git checkout first-pull-request ``` @@ -90,4 +93,4 @@ $ git config --local core.hooksPath .githooks/ --- ### Next -[STEP2: 環境構築](step2.ja.md) \ No newline at end of file +[STEP2: 環境構築](02-local-env.ja.md) \ No newline at end of file diff --git a/document/step2.en.md b/document/02-local-env.en.md similarity index 77% rename from document/step2.en.md rename to document/02-local-env.en.md index 255908a67..76eabb041 100644 --- a/document/step2.en.md +++ b/document/02-local-env.en.md @@ -67,7 +67,7 @@ If the version does not correspond to the Python version you installed, double c ### 3. Install dependencies -In Go, dependent libraries are managed in a file called `go.mod`. +In Go, dependent libraries are managed in a file called `go.mod`. You can install the dependencies by running the following command. ```shell @@ -97,12 +97,16 @@ If successful, you can access the local host `http://127.0.0.1:9000` on our brow The following resources are useful to dive deeper into building environments and Linux. -* [An Introduction to Linux Basics](https://www.digitalocean.com/community/tutorials/an-introduction-to-linux-basics) -* [Linux Mastery: Master the Linux Command Line in 11.5 Hours](https://www.udemy.com/course/linux-mastery/) +* (JA)[book - [試して理解]Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識](https://www.amazon.co.jp/dp/477419607X/ref=cm_sw_r_tw_dp_178K0A3YTGA97XRH318R) +* (JA)[Udemy Business - もう絶対に忘れない Linux コマンド【Linux 100本ノック+名前の由来+丁寧な解説で、長期記憶に焼き付けろ!](https://mercari.udemy.com/course/linux100test/) + * ↑わかりやすい講座だと思い貼ってますが、コマンドの暗記は特にしなくていいです + +* (EN)[An Introduction to Linux Basics](https://www.digitalocean.com/community/tutorials/an-introduction-to-linux-basics) +* (EN)[Udemy Business - Linux Mastery: Master the Linux Command Line in 11.5 Hours](https://mercari.udemy.com/course/linux-mastery/) * You do NOT have to memorize the commands! --- ### Next -[STEP3: Make a listing API](step3.en.md) \ No newline at end of file +[STEP3: Make a listing API](03-api.en.md) \ No newline at end of file diff --git a/document/step2.ja.md b/document/02-local-env.ja.md similarity index 83% rename from document/step2.ja.md rename to document/02-local-env.ja.md index 74b21fae2..607f6eeee 100644 --- a/document/step2.ja.md +++ b/document/02-local-env.ja.md @@ -99,11 +99,15 @@ $ go run app/main.go 環境構築の仕方やlinuxについてさらにしっかり学ぶためには以下の教材がおすすめです。 -* [book - [試して理解]Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識](https://www.amazon.co.jp/dp/477419607X/ref=cm_sw_r_tw_dp_178K0A3YTGA97XRH318R) -* [Udemy - もう絶対に忘れない Linux コマンド【Linux 100本ノック+名前の由来+丁寧な解説で、長期記憶に焼き付けろ!](https://www.udemy.com/course/linux100test/) +* (JA)[book - [試して理解]Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識](https://www.amazon.co.jp/dp/477419607X/ref=cm_sw_r_tw_dp_178K0A3YTGA97XRH318R) +* (JA)[Udemy Business - もう絶対に忘れない Linux コマンド【Linux 100本ノック+名前の由来+丁寧な解説で、長期記憶に焼き付けろ!](https://mercari.udemy.com/course/linux100test/) * ↑わかりやすい講座だと思い貼ってますが、コマンドの暗記は特にしなくていいです +* (EN)[An Introduction to Linux Basics](https://www.digitalocean.com/community/tutorials/an-introduction-to-linux-basics) +* (EN)[Udemy Business - Linux Mastery: Master the Linux Command Line in 11.5 Hours](https://mercari.udemy.com/course/linux-mastery/) + * You do NOT have to memorize the commands! + --- ### Next -[STEP3: 出品APIを作る](step3.ja.md) \ No newline at end of file +[STEP3: 出品APIを作る](03-api.ja.md) \ No newline at end of file diff --git a/document/step3.en.md b/document/03-api.en.md similarity index 56% rename from document/step3.en.md rename to document/03-api.en.md index f12a81e93..59cf64a9a 100644 --- a/document/step3.en.md +++ b/document/03-api.en.md @@ -4,12 +4,12 @@ **:book: Reference** -* (JA) [Udemy -【基礎からわかる!】Webアプリケーションの仕組み](https://www.udemy.com/course/tobach_01_webapp_structure/) +* (JA) [Udemy Business - REST WebAPI サービス 設計](https://mercari.udemy.com/course/rest-webapi-development/) * (JA) [HTTP レスポンスステータスコード](https://developer.mozilla.org/ja/docs/Web/HTTP/Status) * (JA) [HTTP リクエストメソッド](https://developer.mozilla.org/ja/docs/Web/HTTP/Methods) * (JA) [APIとは?意味やメリット、使い方を世界一わかりやすく解説](https://www.sejuku.net/blog/7087) -* (EN) [API and Web Service Introduction](https://www.udemy.com/course/api-and-web-service-introduction/) +* (EN) [Udemy Business - API and Web Service Introduction](https://mercari.udemy.com/course/api-and-web-service-introduction/) * (EN) [HTTP response status codes](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status) * (EN) [HTTP request methods](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods) @@ -91,49 +91,13 @@ $ curl -X GET 'http://127.0.0.1:9000/items' {"items": [{"name": "jacket", "category": "fashion"}, ...]} ``` -## 4. Write into a database - -In the previous step, we saved data into `items.json`. We will move this into a database. -We will use a database called **SQLite**. - -**:book: Reference** - -* (JA)[SQLite入門](https://www.dbonline.jp/sqlite/) -* (JA)[Udemy -【SQLiteで学ぶ】ゼロから始めるデータベースとSQL超入門](https://www.udemy.com/course/basic_database_sqlite/) -* (JA)[Udemy - はじめてのSQLserver データベース SQL未経験者〜初心者向けコース](https://www.udemy.com/course/sqlserver-for-beginner/) -* (EN)[https://www.sqlitetutorial.net/](https://www.sqlitetutorial.net/) -* (EN)[Udemy - Intro To SQLite Databases for Python Programming](https://www.udemy.com/course/using-sqlite3-databases-with-python/) - -Install SQlite, and make a database file called `mercari.sqlite3`. Open this file and make a table called `items`. Define the items table as follows and save the schema into `db/items.db`. - -* id: int (Identifier unique for each item) -* name: string (Name of the item) -* category: string (Category of the item) - -Change the endpoints `GET /items` and `POST /items` such that items are saved into the database and can be returned based on GET request. Add `mercari.sqlite3` to your `.gitignore` such that it is not commited. `items.db` shoud be commited. - -**:beginner: Points** - -* What are the advantages of saving into a databse such as SQLite instead of saving into a single JSON file? - -## 5. Search for an item - -Make an endpoint to return a list of items that include a specified keyword called `GET /search`. - -```shell -# Request a list of items containing string "jacket" -$ curl -X GET 'http://127.0.0.1:9000/search?keyword=jacket' -# Expected response for a list of items with name containing "jacket" -{"items": [{"name": "jacket", "category": "fashion"}, ...]} -``` - -## 6. Add an image to an item +## 4. Add an image to an item Change the endpoints `GET /items` and `POST /items` such that items can have images while listing. * Make a directory called `images` * Hash the image using sha256, and save it with the name `.jpg` -* Modify items table such that the image file can be saved as a string +* Modify items such that the image file can be saved as a string ```shell # POST the jpg file @@ -144,13 +108,10 @@ curl -X POST \ -F 'image=@images/local_image.jpg' ``` +```json +{"items": [{"name": "jacket", "category": "fashion", "image_filename": "510824dfd4caed183a7a7cc2be80f24a5f5048e15b3b5338556d5bbd3f7bc267.jpg"}, ...]} +``` -Items table example: - -| id | name | category | image_filename | -| :--- | :----- | :------- | :------------------------------------------------------------------- | -| 1 | jacket | fashion | 510824dfd4caed183a7a7cc2be80f24a5f5048e15b3b5338556d5bbd3f7bc267.jpg | -| 2 | ... | | | **:beginner: Point** @@ -158,7 +119,7 @@ Items table example: * What other hashing functions are out there except for sha256? -## 7. Return item details +## 5. Return item details Make an endpoint `GET /items/` to return item details. @@ -167,29 +128,7 @@ $ curl -X GET 'http://127.0.0.1:9000/items/1' {"name": "jacket", "category": "fashion", "image": "..."} ``` -## 8. (Optional) Move the category information to a separate table - -Modify the database as follows. This allows changes in the category names and you will not have to change all categories in the items table when they do. Since `GET items` should still return the name of the category, join these two tables when returning responses. - -**items table** - -| id | name | category_id | image_filename | -| :--- | :----- | :---------- | :------------------------------------------------------------------- | -| 1 | jacket | 1 | 510824dfd4caed183a7a7cc2be80f24a5f5048e15b3b5338556d5bbd3f7bc267.jpg | -| 2 | ... | | | - -**category table** - -| id | name | -| :--- | :------ | -| 1 | fashion | -| ... | | - -**:beginner: Points** -* What is database **normalization**? - - -## 9. (Optional) Understand Loggers +## 6. (Optional) Understand Loggers Open `http://127.0.0.1:9000/image/no_image.jpg` on your browser. This returns an image called `no image` but the debug log is not displayed on your console. ``` @@ -215,4 +154,4 @@ Check if you understand the following concepts. ### Next -[STEP4: Run the application in a virtual environment](step4.en.md) \ No newline at end of file +[STEP4: Database](04-database.en.md) diff --git a/document/step3.ja.md b/document/03-api.ja.md similarity index 57% rename from document/step3.ja.md rename to document/03-api.ja.md index 8b0a68887..39d70c424 100644 --- a/document/step3.ja.md +++ b/document/03-api.ja.md @@ -4,12 +4,12 @@ **:book: Reference** -* (JA) [Udemy -【基礎からわかる!】Webアプリケーションの仕組み](https://www.udemy.com/course/tobach_01_webapp_structure/) +* (JA) [Udemy Business - REST WebAPI サービス 設計](https://mercari.udemy.com/course/rest-webapi-development/) * (JA) [HTTP レスポンスステータスコード](https://developer.mozilla.org/ja/docs/Web/HTTP/Status) * (JA) [HTTP リクエストメソッド](https://developer.mozilla.org/ja/docs/Web/HTTP/Methods) * (JA) [APIとは?意味やメリット、使い方を世界一わかりやすく解説](https://www.sejuku.net/blog/7087) -* (EN) [API and Web Service Introduction](https://www.udemy.com/course/api-and-web-service-introduction/) +* (EN) [Udemy Business - API and Web Service Introduction](https://mercari.udemy.com/course/api-and-web-service-introduction/) * (EN) [HTTP response status codes](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status) * (EN) [HTTP request methods](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods) @@ -94,54 +94,14 @@ $ curl -X GET 'http://127.0.0.1:9000/items' {"items": [{"name": "jacket", "category": "fashion"}, ...]} ``` -## 4. Databaseに保存する -ここまで`items.json`に情報を保存してきましたが、このデータをデータベースに移し替えます。 -今回は **SQLite**というデータベースを使います。 - -**:book: Reference** - -* (JA)[SQLite入門](https://www.dbonline.jp/sqlite/) -* (JA)[Udemy -【SQLiteで学ぶ】ゼロから始めるデータベースとSQL超入門](https://www.udemy.com/course/basic_database_sqlite/) -* (JA)[Udemy - はじめてのSQLserver データベース SQL未経験者〜初心者向けコース](https://www.udemy.com/course/sqlserver-for-beginner/) -* (EN)[https://www.sqlitetutorial.net/](https://www.sqlitetutorial.net/) -* (EN)[Udemy - Intro To SQLite Databases for Python Programming](https://www.udemy.com/course/using-sqlite3-databases-with-python/) - -SQLiteをインストールし、dbフォルダに、`mercari.sqlite3` というデータベースファイルを作成します。 -`mercari.sqlite3`を開き、`items`テーブルを作成します。 - -itemsテーブルは以下のように定義し、スキーマを `db/items.db` に保存します。 - -* id: int 商品ごとにユニークなID -* name: string 商品の名前 -* category: string 商品のカテゴリ - -データがデータベースに保存され、商品一覧情報を取り出すことができるように、`GET /items`と`POST /items`のエンドポイントを変更しましょう。 - -`items.db`はgitの管理対象にしますが、`mercari.sqlite3`はgitの管理対象として追加しないようにしてください。 - -**:beginner: Point** - -* jsonファイルではなくデータベース(SQLite)にデータを保存する利点は何がありますか? - -## 5. 商品を検索する - -指定したキーワードを含む商品一覧を返す、`GET /search`エンドポイントを作ります。 - -```shell -# "jacket"という文字を含む商品一覧をリクエストする -$ curl -X GET 'http://127.0.0.1:9000/search?keyword=jacket' -# "jacket"をnameに含む商品一覧が返ってくる -{"items": [{"name": "jacket", "category": "fashion"}, ...]} -``` - -## 6. 画像を登録する +## 4. 画像を登録する 商品情報に画像(image)を登録できるように、`GET /items`と`POST /items`のエンドポイントを変更します。 * 画像は `images` というフォルダを作成し保存します -* ポストされた画像のファイル名を sha256 で hash化し、`.jpg`という名前で保存します -* itemsテーブルに画像のファイル名をstringで保存できるように変更を加えます +* ポストされた画像のファイルを sha256 で hash化し、`.jpg`という名前で保存します +* itemsに画像のファイル名をstringで保存できるように変更を加えます ```shell # ローカルから.jpgをポストする @@ -153,19 +113,17 @@ curl -X POST \ ``` -Items table example: +```json +{"items": [{"name": "jacket", "category": "fashion", "image_filename": "510824dfd4caed183a7a7cc2be80f24a5f5048e15b3b5338556d5bbd3f7bc267.jpg"}, ...]} +``` -| id | name | category | image_filename | -| :--- | :----- | :------- | :------------------------------------------------------------------- | -| 1 | jacket | fashion | 510824dfd4caed183a7a7cc2be80f24a5f5048e15b3b5338556d5bbd3f7bc267.jpg | -| 2 | ... | | | **:beginner: Point** * Hash化とはなにか? * sha256以外にどんなハッシュ関数があるか調べてみましょう -## 7. 商品の詳細を返す +## 5. 商品の詳細を返す 商品の詳細情報を取得する `GET /items/` というエンドポイントを作成します。 @@ -174,31 +132,7 @@ $ curl -X GET 'http://127.0.0.1:9000/items/1' {"name": "jacket", "category": "fashion", "image_filename": "..."} ``` -## 8. (Optional) カテゴリの情報を別のテーブルに移す - -データベースを以下のように構成しなおします。 -これによってカテゴリの名前が途中で変わったとしても、全部のitemsテーブルのcategoryを修正する必要がなくなります。 -`GET items`ではcategoryの名前を変わらず取得したいので、テーブルをjoinしてレスポンス用のデータを作って返しましょう。 - -**items table** - -| id | name | category_id | image_filename | -| :--- | :----- | :---------- | :------------------------------------------------------------------- | -| 1 | jacket | 1 | 510824dfd4caed183a7a7cc2be80f24a5f5048e15b3b5338556d5bbd3f7bc267.jpg | -| 2 | ... | | | - -**category table** - -| id | name | -| :--- | :------ | -| 1 | fashion | -| ... | | - -**:beginner: Point** -* データベースの**正規化**とは何でしょうか? - - -## 9. (Optional) Loggerについて調べる +## 6. (Optional) Loggerについて調べる `http://127.0.0.1:9000/image/no_image.jpg`にアクセスしてみましょう。 `no image`という画像が帰ってきますが、 コード中にある ``` @@ -206,7 +140,7 @@ Image not found: ``` というデバッグログがコンソールに表示されません。 これはなぜか、調べてみましょう。 -これを表示するためには、どこを変更したらいいでしょうか? +これを表示するためには、コードのどこを変更したらいいでしょうか? **:beginner: Point** * Log levelとは? @@ -226,4 +160,4 @@ Image not found: ### Next -[STEP4: 仮想環境でアプリを動かす](step4.ja.md) +[STEP5: データベース](04-database.ja.md) diff --git a/document/04-database.en.md b/document/04-database.en.md new file mode 100644 index 000000000..88b334b51 --- /dev/null +++ b/document/04-database.en.md @@ -0,0 +1,68 @@ +# STEP4: Database +In the previous step, we saved data into `items.json`. We will move this into a database. + +**:book: Reference** + +* (JA)[SQLite入門](https://www.dbonline.jp/sqlite/) +* (JA)[Udemy Business - データベース講座1:データベース論理設計](https://mercari.udemy.com/course/database-logic/) + +* (EN)[https://www.sqlitetutorial.net/](https://www.sqlitetutorial.net/) +* (EN)[Udemy Business - SQLite for beginners](https://mercari.udemy.com/course/sqlite-for-beginners/) +* (EN)[Udemy Business - Relational Database Designs](https://mercari.udemy.com/course/relational-database-design/) +## 1. Write into a database +We will use a database called **SQLite**. + +* Install SQlite, and make a database file called `mercari.sqlite3`. +* Open this file and make a table called `items`. +* Define the items table as follows and save the schema into `db/items.db`. + * id: int (Identifier unique for each item) + * name: string (Name of the item) + * category: string (Category of the item) + * image_name: string (Filename of the imeage) + +Change the endpoints `GET /items` and `POST /items` such that items are saved into the database and can be returned based on GET request. Add `mercari.sqlite3` to your `.gitignore` such that it is not commited. `items.db` shoud be commited. + +**:beginner: Points** + +* What are the advantages of saving into a database such as SQLite instead of saving into a single JSON file? + +## 2. Search for an item + +Make an endpoint to return a list of items that include a specified keyword called `GET /search`. + +```shell +# Request a list of items containing string "jacket" +$ curl -X GET 'http://127.0.0.1:9000/search?keyword=jacket' +# Expected response for a list of items with name containing "jacket" +{"items": [{"name": "jacket", "category": "fashion"}, ...]} +``` + +## 8. Move the category information to a separate table + +Modify the database as follows. That makes it possible to change the category names without modifying the all categories of items in the items table. +Since `GET items` should return the category name as before, **join** these two tables when returning responses. + +**items table** + +| id | name | category_id | image_filename | +| :--- | :----- | :---------- | :------------------------------------------------------------------- | +| 1 | jacket | 1 | 510824dfd4caed183a7a7cc2be80f24a5f5048e15b3b5338556d5bbd3f7bc267.jpg | +| 2 | ... | | | + +**category table** + +| id | name | +| :--- | :------ | +| 1 | fashion | +| ... | | + +**:beginner: Points** +* What is database **normalization**? + + + +--- + +### Next + +[STEP5: Run the application in a virtual environment](05-docker.en.md) \ No newline at end of file diff --git a/document/04-database.ja.md b/document/04-database.ja.md new file mode 100644 index 000000000..be1b6c4a6 --- /dev/null +++ b/document/04-database.ja.md @@ -0,0 +1,81 @@ +# STEP4: データベース + +ここまで`items.json`に情報を保存してきましたが、このデータをデータベースに移し替えます。 + +**:book: Reference** + +* (JA)[SQLite入門](https://www.dbonline.jp/sqlite/) +* (JA)[Udemy Business - データベース講座1:データベース論理設計](https://mercari.udemy.com/course/database-logic/) + +* (EN)[https://www.sqlitetutorial.net/](https://www.sqlitetutorial.net/) +* (EN)[Udemy Business - SQLite for beginners](https://mercari.udemy.com/course/sqlite-for-beginners/) +* (EN)[Udemy Business - Relational Database Designs](https://mercari.udemy.com/course/relational-database-design/) + +## 1. SQLiteに情報を移行する +今回は **SQLite**というデータベースを使います。 + +* SQLiteをインストール +* dbフォルダに、`mercari.sqlite3` というデータベースファイルを作成 +* `mercari.sqlite3`を開き、`items`テーブルを作成 +* `items`テーブルは以下のように定義し、スキーマを `db/items.db` に保存します。 + * id: int 商品ごとにユニークなID + * name: string 商品の名前 + * category: string 商品のカテゴリ + * image_name: string 画像のパス + +`items.db`はgitの管理対象にしますが、`mercari.sqlite3`はgitの管理対象として追加しないようにしてください。 + +データがデータベースに保存され、商品一覧情報を取り出すことができるように、`GET /items`と`POST /items`のエンドポイントを変更しましょう。 + + +Items table example: + +| id | name | category | image_name | +| :--- | :----- | :------- |:---------------------------------------------------------------------| +| 1 | jacket | fashion | 510824dfd4caed183a7a7cc2be80f24a5f5048e15b3b5338556d5bbd3f7bc267.jpg | +| 2 | ... | | | + + +**:beginner: Point** + +* jsonファイルではなくデータベース(SQLite)にデータを保存する利点は何がありますか? + +## 2. 商品を検索する + +指定したキーワードを含む商品一覧を返す、`GET /search`エンドポイントを作ります。 + +```shell +# "jacket"という文字を含む商品一覧をリクエストする +$ curl -X GET 'http://127.0.0.1:9000/search?keyword=jacket' +# "jacket"をnameに含む商品一覧が返ってくる +{"items": [{"name": "jacket", "category": "fashion"}, ...]} +``` + +## 3. カテゴリの情報を別のテーブルに移す + +データベースを以下のように構成しなおします。 +これによってカテゴリの名前を途中で変えたとしても、全部のitemsテーブルのcategoryを修正する必要がなくなります。 +`GET items`ではこれまでと同様にcategoryの名前を取得したいので、テーブルを**join**してレスポンス用のデータを作って返すように実装を更新しましょう。 + +**items table** + +| id | name | category_id | image_filename | +| :--- | :----- | :---------- | :------------------------------------------------------------------- | +| 1 | jacket | 1 | 510824dfd4caed183a7a7cc2be80f24a5f5048e15b3b5338556d5bbd3f7bc267.jpg | +| 2 | ... | | | + +**category table** + +| id | name | +| :--- | :------ | +| 1 | fashion | +| ... | | + +**:beginner: Point** +* データベースの**正規化**とは何でしょうか? + +--- + +### Next + +[STEP5: 仮想環境でアプリを動かす](05-docker.ja.md) diff --git a/document/step4.en.md b/document/05-docker.en.md similarity index 82% rename from document/step4.en.md rename to document/05-docker.en.md index 640d24ae8..168033b67 100644 --- a/document/step4.en.md +++ b/document/05-docker.en.md @@ -1,11 +1,14 @@ -# STEP4: Run the application in a virtual environment +# STEP5: Run the application in a virtual environment In this step, we will learn how to use Docker. **:book: Reference** -* [docker docs](https://docs.docker.com/get-started/overview/) -* [Udemy - ゼロからはじめる Dockerによるアプリケーション実行環境構築](https://www.udemy.com/course/docker-k/) +* (JA)[docker docs](https://matsuand.github.io/docs.docker.jp.onthefly/get-started/overview/) +* (JA)[Udemy Business - ゼロからはじめる Dockerによるアプリケーション実行環境構築](https://mercari.udemy.com/course/docker-k/) + +* (EN)[docker docs](https://docs.docker.com/get-started/overview/) +* (EN)[Udemy Business - Docker for the Absolute Beginner - Hands On - DevOps](https://mercari.udemy.com/course/learn-docker/) ## 1. Install Docker **Install docker of the latest version, and check if you can run `docker -v`.** @@ -16,7 +19,7 @@ In this step, we will learn how to use Docker. ## 2. Run Docker commands -**Make sure that you're in `mercari-build-training-2022/` directory, and run the following command.** +**Make sure that you're in `mercari-build-training-2023/` directory, and run the following command.** ```shell $ docker run -v $(pwd)/data/text_en.png:/tmp/img.png wakanapo/tesseract-ocr tesseract /tmp/img.png stdout -l eng @@ -95,9 +98,9 @@ ERRO[0000] error waiting for container: context canceled `"python"` part will be replaced with `"go"` if you're using Go. -**Modify the `dockerfile` so that you can use the same version of Python/Go as STEP2 in your docker image.** +**Modify the `Dockerfile` so that you can use the same version of Python/Go as STEP2 in your docker image.** -Run the image with the modified `dockerfile`, check if the same message is displayed as STEP2-2. +Run the image with the modified `Dockerfile`, check if the same message is displayed as STEP2-2. **:book: Reference** @@ -130,4 +133,4 @@ Make sure you understand the following concepts ### Next -[STEP5: Implement a simple Mercari webapp as frontend](step5.en.md) \ No newline at end of file +[STEP5: Implement a simple Mercari webapp as frontend](07-frontend.en.md) \ No newline at end of file diff --git a/document/step4.ja.md b/document/05-docker.ja.md similarity index 85% rename from document/step4.ja.md rename to document/05-docker.ja.md index 0039e22b7..615fee42a 100644 --- a/document/step4.ja.md +++ b/document/05-docker.ja.md @@ -1,12 +1,14 @@ -# STEP4: 仮想環境でアプリを動かす +# STEP5: 仮想環境でアプリを動かす このステップでは docker の使い方を学びます。 **:book: Reference** -* [docker docs](https://matsuand.github.io/docs.docker.jp.onthefly/get-started/overview/) -* [Udemy - ゼロからはじめる Dockerによるアプリケーション実行環境構築](https://www.udemy.com/course/docker-k/) +* (JA)[docker docs](https://matsuand.github.io/docs.docker.jp.onthefly/get-started/overview/) +* (JA)[Udemy Business - ゼロからはじめる Dockerによるアプリケーション実行環境構築](https://mercari.udemy.com/course/docker-k/) +* (EN)[docker docs](https://docs.docker.com/get-started/overview/) +* (EN)[Udemy Business - Docker for the Absolute Beginner - Hands On - DevOps](https://mercari.udemy.com/course/learn-docker/) ## 1. Docker をインストールする **最新のdockerをインストールし、`docker -v` が実行できることを確認しましょう。** @@ -74,11 +76,11 @@ docker はホスト上に存在しないイメージを使う際には、自動 ## 4. Docker Image を Build する -**pythonで開発をしている人は`python/`, Goの人は`go/`以下にある`dockerfile`をbuildしてみましょう。** +**pythonで開発をしている人は`python/`, Goの人は`go/`以下にある`Dockerfile`をbuildしてみましょう。** -* 名前(リポジトリ名)は `build2022/app`, タグは`latest` とします。 +* 名前(リポジトリ名)は `build2023/app`, タグは`latest` とします。 -イメージ一覧の中に `build2022/app` という image があれば成功です。 +イメージ一覧の中に `build2023/app` という image があれば成功です。 **:book: Reference** @@ -91,7 +93,7 @@ docker はホスト上に存在しないイメージを使う際には、自動 ``` docker: Error response from daemon: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "python": executable file not found in $PATH: unknown. ERRO[0000] error waiting for container: context canceled -``` +``` Goの場合は、上のエラーメッセージの`"python"`の部分が`"go"`になります。 @@ -110,7 +112,7 @@ STEP4-5 までで docker image の中は STEP2-2 と同じ状態になってい **`dockerfile`を変更し、必要なファイルをコピーしたり依存ライブラリをインストールしたりして, docker image 上で 出品 API が動くようにしましょう。** -`$ docker run -d -p 9000:9000 build2022/app:latest` +`$ docker run -d -p 9000:9000 build2023/app:latest` を実行しSTEP3と同様にしてAPIを叩ければ成功です。 @@ -129,4 +131,4 @@ STEP4-5 までで docker image の中は STEP2-2 と同じ状態になってい ### Next -[STEP5: Webのフロントエンドを実装する](step5.ja.md) \ No newline at end of file +[STEP5: Webのフロントエンドを実装する](07-frontend.ja.md) \ No newline at end of file diff --git a/document/06-ci.en.md b/document/06-ci.en.md new file mode 100644 index 000000000..906bea0df --- /dev/null +++ b/document/06-ci.en.md @@ -0,0 +1,43 @@ +# STEP6: Build Docker image using CI + +In this step you will learn how to use CI. + +**:book: Reference** + +* (JA)[継続的インテグレーションについて](https://docs.github.com/ja/actions/automating-builds-and-tests/about-continuous-integration) +* (JA)[Udemy Business - 【新UI対応】Amazon ECS × GitHub Actionsで始めるコンテナベースのアプリケーション開発](https://mercari.udemy.com/course/ecs-githubactions/) + * You can ignore the lectures about Amazon ECS + +* (EN)[About continuous integration](https://docs.github.com/en/actions/automating-builds-and-tests/about-continuous-integration) +* (EN)[Udemy Business - The Complete GitHub Actions & Workflows Guide](https://mercari.udemy.com/course/github-actions/) +## 1. About CI +CI is an abbreviation for Continuous Integration. +A process that automatically builds, tests, and more every time you push or merge code. +There are many people who do not have the opportunity to use CI if they are developing alone. + +First learn more about CI by looking into the Reference and Udemy page. + +## 2. Enable Github Actions +Github offers a CI service called Github Actions. +First, enable Github Actions on your repository. + +- [Enable Workflow](https://docs.github.com/en/actions/managing-workflow-runs/disabling-and-enabling-a-workflow) + +After enabling Workflow, create an commit and confirm that the Github Actions Workflow works, by pushing to the repository as a trigger. +The workflow works if :white_check_mark: or :red_circle: is displayed next to the commit comment as shown in the figure below. +![Enable workflow](../data/workflow-enable.png) + +## 3. Build the application with Github Actions and upload the docker image to the registry +The file `.github/workflows/build.yml` already contains a workflow that pushes your code to the registry, + +```yaml +# - name: Build and push Docker image +``` + +Remove the comment out from the Step and push the docker image via CI. + +If the Workflow is successful, the generated image will be pushed to the URL: `ghcr.io//mercari-build-training-2023:`. +Pull the image locally and run it. + +Reference +- [Publishing and installing a package with GitHub Actions](https://docs.github.com/en/packages/managing-github-packages-using-github-actions-workflows/publishing-and-installing-a-package-with-github-actions#upgrading-a-workflow-that-accesses-a-registry-using-a-personal-access-token) diff --git a/document/06-ci.ja.md b/document/06-ci.ja.md new file mode 100644 index 000000000..80d09734f --- /dev/null +++ b/document/06-ci.ja.md @@ -0,0 +1,41 @@ +# STEP6: CIを使ってDocker imageをBuildする + +このステップでは CI の使い方を学びます。 +**:book: Reference** + +* (JA)[継続的インテグレーションについて](https://docs.github.com/ja/actions/automating-builds-and-tests/about-continuous-integration) +* (JA)[Udemy Business - 【新UI対応】Amazon ECS × GitHub Actionsで始めるコンテナベースのアプリケーション開発](https://mercari.udemy.com/course/ecs-githubactions/) + * Amazon ECSのパートは飛ばして大丈夫です + +* (EN)[About continuous integration](https://docs.github.com/en/actions/automating-builds-and-tests/about-continuous-integration) +* (EN)[Udemy Business - The Complete GitHub Actions & Workflows Guide](https://mercari.udemy.com/course/github-actions/) +## 1. CIを理解する +CIとはContinuous Integration(継続的インテグレーション)の略語で、 +コードをpushしたりmergeしたりするたびに自動的にビルドやテストなどを行うプロセスです。 +一人で開発していると使う機会がない方も多いと思います。 + +まずはReferenceにあるページやUdemyを参考に、CIについて勉強しましょう。 + +## 2. Github Actionsを有効にする +GithubはGithub Actionsと呼ばれるCIサービスを提供しています。 +まずは皆さんのリポジトリでGithub Actionを有効化します。 + +- [ワークフローの有効化](https://docs.github.com/ja/actions/managing-workflow-runs/disabling-and-enabling-a-workflow) + +有効にしたら、適当なcommitを作成し、PushをトリガーにGithub Actionsのワークフローが動くことを確認します。 +以下の図のように:white_check_mark:や:red_circle:がcommit commentの横に表示されていれば動いています。 +![Enable workflow](../data/workflow-enable.png) + +## 3. アプリケーションをGithubActionsでビルドして、docker imageをregistryにupする +`.github/workflows/build.yml`にregistryにあなたのコードをpushするフローが書かれているので、 + +```yaml +# - name: Build and push Docker image +``` +のStepのコメントアウトを外し、CI経由でdocker imageをpushさせてみましょう。 + +うまくいくと `ghcr.io//mercari-build-training-2023:` +というURLにimageがpushされるので、ローカルでそのimageをpullして実行してみましょう。 + +Reference +- [GitHub Actionsでのパッケージの公開とインストール](https://docs.github.com/ja/packages/managing-github-packages-using-github-actions-workflows/publishing-and-installing-a-package-with-github-actions#upgrading-a-workflow-that-accesses-a-registry-using-a-personal-access-token) diff --git a/document/step5.en.md b/document/07-frontend.en.md similarity index 93% rename from document/step5.en.md rename to document/07-frontend.en.md index 1bba5e963..40bdeda4a 100644 --- a/document/step5.en.md +++ b/document/07-frontend.en.md @@ -1,4 +1,4 @@ -# STEP5: Implement a simple Mercari webapp as frontend +# STEP7: Implement a simple Mercari webapp as frontend ## 1. Build local environment @@ -26,7 +26,7 @@ Run the backend servers in Python/Go as described in Step3. This simple web application allows you to do two things - Add a new item (Listing) - View the list of itemas (ItemList) - + These functionalities are carved out as components called `src/components/Listing` and `src/components/ItemList`, and called from the main `App.tsx`. :pushpin: Sample code is in React but the knowledge of React is not necessary. @@ -37,7 +37,7 @@ Use the listing form to add a new item. In this screen, you can input name, cate If your API from STEP3 only accepts name and category, modify `typescript/simple-mercari-web/src/components/Listing/Listing.tsx` and delete the image field. -### (Optional) Task 2. Show item images +### (Optional) Task 2. Show item images In this screen, item images are all rendered as Build@Mercari logo. Specify the item image as `http://localhost:9000/image/.jpg` and see if they can be displayed on the web app. @@ -74,4 +74,4 @@ Current `ItemList` shows one column of items sequentially. Use the following ref ### Next -[STEP6: Run frontend and API using docker-compose](step6.en.md) \ No newline at end of file +[STEP6: Run frontend and API using docker-compose](08-docker-compose.en.md) \ No newline at end of file diff --git a/document/step5.ja.md b/document/07-frontend.ja.md similarity index 97% rename from document/step5.ja.md rename to document/07-frontend.ja.md index 5b1a71176..7d69d853b 100644 --- a/document/step5.ja.md +++ b/document/07-frontend.ja.md @@ -1,4 +1,4 @@ -# STEP5: Webのフロントエンドを実装する +# STEP7: Webのフロントエンドを実装する ## 1. 環境構築 以下からv16のNodeをインストールしてください。 @@ -70,4 +70,4 @@ CSSだけではなく、各コンポーネントでreturnされているHTMLタ ### Next -[STEP6: docker-composeでAPIとフロントエンドを動かす](step6.ja.md) \ No newline at end of file +[STEP6: docker-composeでAPIとフロントエンドを動かす](08-docker-compose.ja.md) \ No newline at end of file diff --git a/document/step6.en.md b/document/08-docker-compose.en.md similarity index 69% rename from document/step6.en.md rename to document/08-docker-compose.en.md index 2c986f109..e46bb0ab1 100644 --- a/document/step6.en.md +++ b/document/08-docker-compose.en.md @@ -1,22 +1,25 @@ -# STEP6: Run frontend and API using docker-compose +# STEP8: Run frontend and API using docker-compose In this step, we will learn how to use docker-compose. **:book: Reference** -* [Docker Compose Overview](https://docs.docker.com/compose/) -* [Udemy - Hands on With Docker & Docker Compose From a Docker Captain](https://www.udemy.com/course/hands-on-with-docker-and-docker-compose/) +* (JA)[Docker Compose の概要](https://matsuand.github.io/docs.docker.jp.onthefly/compose/) +* (JA)[Udemy Business - 駆け出しエンジニアのためのDocker入門](https://mercari.udemy.com/course/docker-startup/) + +* (EN)[Docker Compose Overview](https://docs.docker.com/compose/) +* (EN)[Udemy Business - Docker for the Absolute Beginner - Hands On - DevOps](https://mercari.udemy.com/course/learn-docker/) ## 1. (Revision) Building Docker Images **Revisit STEP4 and build a docker image for running the web frontend** -You have a sample `dockerfile` In `typescript/simple-mercari-web`. Modify this file to run frontend on Docker. +You have a sample `Dockerfile` In `typescript/simple-mercari-web`. Modify this file to run frontend on Docker. -* Set the name of the repository as `build2022/web` and tag as `latest`. +* Set the name of the repository as `build2023/web` and tag as `latest`. Run the following and check if you can successfully open [http://localhost:3000/](http://localhost:3000/) on your browser. -`$ docker run -d -p 3000:3000 build2022/web:latest` +`$ docker run -d -p 3000:3000 build2023/web:latest` ## 2. Installing Docker Compose @@ -43,18 +46,18 @@ Let's check if you can answer the following questions. **Referring to the tutorial material, run the frontend and API using Docker Compose** -Set up `docker-compose.yml` under `mercari-build-training-2022/` +Set up `docker-compose.yml` under `mercari-build-training-2023/` Make a new file `docker-compose.yml` considering the following points. * Docker image to use - * (Option 1: Difficulty ☆) Use `build2022/app:latest` and `build2022/web:latest` made in STEP4 and STEP6-1 - * (Option 2: Difficulty ☆☆☆) Build from `{go|python}/dockerfile` and `typescript/simple-mercari-web/dockerfile` + * (Option 1: Difficulty ☆) Use `build2023/app:latest` and `build2023/web:latest` made in STEP4 and STEP6-1 + * (Option 2: Difficulty ☆☆☆) Build from `{go|python}/Dockerfile` and `typescript/simple-mercari-web/Dockerfile` * Port numbers * API : 9000 * Frontend : 3000 * Connecting betweeen services - * Frontend should send requests to an environment variable `API_URL` + * Frontend should send requests to an environment variable `REACT_APP_API_URL` * While API will not send requests to frontend, [CORS](https://developer.mozilla.org/ja/docs/Web/HTTP/CORS) needs to be set up such that frontend knows where the requests are coming from * Set an environment variable `FRONT_URL` for frontend URL diff --git a/document/step6.ja.md b/document/08-docker-compose.ja.md similarity index 75% rename from document/step6.ja.md rename to document/08-docker-compose.ja.md index cb54bcf85..1a6d1fb79 100644 --- a/document/step6.ja.md +++ b/document/08-docker-compose.ja.md @@ -1,20 +1,23 @@ -# STEP6: docker-composeでAPIとフロントエンドを動かす +# STEP8: docker-composeでAPIとフロントエンドを動かす このステップでは docker-compose の使い方を学びます。 **:book: Reference** -* [Docker Compose の概要](https://matsuand.github.io/docs.docker.jp.onthefly/compose/) -* [Udemy - 駆け出しエンジニアのためのDocker入門](https://www.udemy.com/course/docker-startup/) +* (JA)[Docker Compose の概要](https://matsuand.github.io/docs.docker.jp.onthefly/compose/) +* (JA)[Udemy Business - 駆け出しエンジニアのためのDocker入門](https://mercari.udemy.com/course/docker-startup/) + +* (EN)[Docker Compose Overview](https://docs.docker.com/compose/) +* (EN)[Udemy Business - Docker for the Absolute Beginner - Hands On - DevOps](https://mercari.udemy.com/course/learn-docker/) ## 1. (復習) フロントエンドの docker image を作成する **STEP4を思い出しながらフロントエンドの docker image を作成しましょう。** -`typescript/simple-mercari-web`以下にフロントエンド用の `dockerfile` がすでに用意されています。これを変更しフロントエンドが docker 上で立ち上がるようにしましょう。 +`typescript/simple-mercari-web`以下にフロントエンド用の `Dockerfile` がすでに用意されています。これを変更しフロントエンドが docker 上で立ち上がるようにしましょう。 -* 名前(リポジトリ名)は `build2022/web`, タグは`latest` とします。 +* 名前(リポジトリ名)は `build2023/web`, タグは`latest` とします。 -`$ docker run -d -p 3000:3000 build2022/web:latest` +`$ docker run -d -p 3000:3000 build2023/web:latest` を実行し、ブラウザから[http://localhost:3000/](http://localhost:3000/)が正しく開ければ成功です。 @@ -41,18 +44,18 @@ ## 4. Docker ComposeでAPIとフロントエンドを動かす **チュートリアルを参考にしながら、今回作成したサービスのフロントエンドとバックエンドのAPIをDocker Composeで動かせるようにしましょう** -`docker-compose.yml` は `mercari-build-training-2022/` 以下に作成することにします。 +`docker-compose.yml` は `mercari-build-training-2023/` 以下に作成することにします。 以下の点を参考にしながら `docker-compose.yml` を作成しましょう。 * 使用する docker image - * (Option 1: 難易度 ☆) STEP4 と STEP6-1 でそれぞれ build した `build2022/app:latest` と `build2022/web:latest` を使う - * (Option 2: 難易度 ☆☆☆) `{go|python}/dockerfile` と `typescript/simple-mercari-web/dockerfile` から build するようにする + * (Option 1: 難易度 ☆) STEP4 と STEP6-1 でそれぞれ build した `build2023/app:latest` と `build2023/web:latest` を使う + * (Option 2: 難易度 ☆☆☆) `{go|python}/Dockerfile` と `typescript/simple-mercari-web/Dockerfile` から build するようにする * 使用する port * API : 9000 * フロントエンド : 3000 * サービス間の接続 - * フロントエンドは`API_URL`という環境変数で設定されたURLのAPIにリクエストを送ります + * フロントエンドは`REACT_APP_API_URL`という環境変数で設定されたURLのAPIにリクエストを送ります * APIはフロントエンドにリクエストは送りませんが[CORS](https://developer.mozilla.org/ja/docs/Web/HTTP/CORS)という仕組みのために、どこからリクエストが来るのか知っておく必要があります `FRONT_URL`という環境変数でフロントエンドのURLを指定しています diff --git a/document/team-hackathon.en.md b/document/10-team-hackathon.en.md similarity index 89% rename from document/team-hackathon.en.md rename to document/10-team-hackathon.en.md index e11a92b66..6e9ff77b0 100644 --- a/document/team-hackathon.en.md +++ b/document/10-team-hackathon.en.md @@ -2,20 +2,20 @@ Form a team and propose and develop a new listing feature at Mercari. -For example, +For example, * A better and more user-friendly UI * Allow videos for listing * Use OCR for automatically input the item title * Speech-to-text input -Any types of improvement on the listing feature are welcome in different aspects like UI, Backend or AI. +Any types of improvement on the listing feature are welcome in different aspects like UI, Backend or AI. ## Development Process * Choose one person to create a repository on GitHub - * Make the repository public and add everyone in your Hackathon team as contributors + * Make the repository public and add everyone in your Hackathon team as contributors * Each team member should contribute via Pull Requests and work from their own branch **:beginner: Point** diff --git a/document/team-hackathon.ja.md b/document/10-team-hackathon.ja.md similarity index 100% rename from document/team-hackathon.ja.md rename to document/10-team-hackathon.ja.md diff --git a/go/dockerfile b/go/dockerfile index 6cd4595dc..138882f6e 100644 --- a/go/dockerfile +++ b/go/dockerfile @@ -1,4 +1,8 @@ FROM alpine -# STEP4-4では以下は変更しない +RUN addgroup -S mercari && adduser -S trainee -G mercari +# RUN chown -R trainee:mercari /path/to/db + +USER trainee + CMD ["go", "version"] diff --git a/go/go.mod b/go/go.mod index 2265223e0..7c8c43a9d 100644 --- a/go/go.mod +++ b/go/go.mod @@ -1,4 +1,4 @@ -module mercari-build-training-2022 +module mercari-build-training-2023 go 1.17 diff --git a/python/dockerfile b/python/dockerfile index 1907f2e61..08ddc2336 100644 --- a/python/dockerfile +++ b/python/dockerfile @@ -1,4 +1,8 @@ FROM alpine -# STEP4-4では以下は変更しない +RUN addgroup -S mercari && adduser -S trainee -G mercari +# RUN chown -R trainee:mercari /path/to/db + +USER trainee + CMD ["python", "-V"] diff --git a/typescript/simple-mercari-web/dockerfile b/typescript/simple-mercari-web/dockerfile index 238604b9f..2ffd5a655 100644 --- a/typescript/simple-mercari-web/dockerfile +++ b/typescript/simple-mercari-web/dockerfile @@ -1,3 +1,7 @@ FROM node:16-alpine WORKDIR /app + +RUN addgroup -S mercari && adduser -S trainee -G mercari +USER trainee + CMD ["node", "-v"] diff --git a/typescript/simple-mercari-web/public/index.html b/typescript/simple-mercari-web/public/index.html index a27a40aa6..baa091556 100644 --- a/typescript/simple-mercari-web/public/index.html +++ b/typescript/simple-mercari-web/public/index.html @@ -7,7 +7,7 @@ - Build@Mercari 2022 + Build@Mercari 2023 diff --git a/typescript/simple-mercari-web/public/manifest.json b/typescript/simple-mercari-web/public/manifest.json index 044cfb371..674d94f24 100644 --- a/typescript/simple-mercari-web/public/manifest.json +++ b/typescript/simple-mercari-web/public/manifest.json @@ -1,6 +1,6 @@ { - "short_name": "Build @ Mercari 2022", - "name": "Frontend for Build@Mercari 2022", + "short_name": "Build @ Mercari 2023", + "name": "Frontend for Build@Mercari 2023", "icons": [ { "src": "favicon.ico", diff --git a/typescript/simple-mercari-web/src/components/ItemList/ItemList.tsx b/typescript/simple-mercari-web/src/components/ItemList/ItemList.tsx index bdbd31697..419728989 100644 --- a/typescript/simple-mercari-web/src/components/ItemList/ItemList.tsx +++ b/typescript/simple-mercari-web/src/components/ItemList/ItemList.tsx @@ -7,7 +7,7 @@ interface Item { image_filename: string; }; -const server = process.env.API_URL || 'http://127.0.0.1:9000'; +const server = process.env.REACT_APP_API_URL || 'http://127.0.0.1:9000'; const placeholderImage = process.env.PUBLIC_URL + '/logo192.png'; interface Prop { diff --git a/typescript/simple-mercari-web/src/components/Listing/Listing.tsx b/typescript/simple-mercari-web/src/components/Listing/Listing.tsx index b990e68b7..94e31da49 100644 --- a/typescript/simple-mercari-web/src/components/Listing/Listing.tsx +++ b/typescript/simple-mercari-web/src/components/Listing/Listing.tsx @@ -1,6 +1,6 @@ import React, { useState } from 'react'; -const server = process.env.API_URL || 'http://127.0.0.1:9000'; +const server = process.env.REACT_APP_API_URL || 'http://127.0.0.1:9000'; interface Prop { onListingCompleted?: () => void;