Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

第一部 - サーバー演習問題 #35

Merged
merged 2 commits into from
Oct 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ dist-ssr
*.sw?

.textlintcache
/.vitepress/cache
60 changes: 31 additions & 29 deletions docs/chapter1/section3/3_server-exercise.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pong
$ curl -X GET "http://localhost:8080/ping" # pong
```
:::details 解答
<<<@/chapter1/section3/src/4-1_ping.go
<<<@/chapter1/section3/src/4-1_ping.rs
:::

## 基本問題 GET /fizzbuzz
Expand Down Expand Up @@ -74,7 +74,7 @@ $ curl -X GET "http://localhost:8080/fizzbuzz?count=a" # Bad Request
**/fizzbuzzが上手く動いたら、講習会の実況用チャンネルに↑の実行結果を投稿しましょう!**

:::details 解答
<<<@/chapter1/section3/src/4-2_fizzbuzz.go
<<<@/chapter1/section3/src/4-2_fizzbuzz.rs
:::

## 基本問題 POST /add
Expand Down Expand Up @@ -117,7 +117,7 @@ $ curl -X POST "http://localhost:8080/add" -H "Content-Type: application/json" -
$ curl -X POST "http://localhost:8080/add" -H "Content-Type: application/json" -d '{"left": 100}' # Bad Request
```
:::details 解答
<<<@/chapter1/section3/src/4-3_add.go
<<<@/chapter1/section3/src/4-3_add.rs
:::

## 発展問題 GET /students/:class/:studentNumber
Expand Down Expand Up @@ -175,19 +175,23 @@ status code: `404`
```

:::tip
ヒント: 最後の課題のデータは次のような構造体を用意して、json.Unmarshal すると定義しやすいです。
```go
type Student struct {
Number int `json:"student_number"`
Name string `json:"name"`
ヒント: 最後の課題のデータは次のような構造体を用意して、serde_json::from_str すると定義しやすいです。
```rs
#[derive(serde::Serialize, serde::Deserialize, clone::Clone)]
struct Student {
student_number: u32,
name: String,
}
type Class struct {
Number int `json:"class_number"`
Students []Student `json:"students"`

#[derive(serde::Deserialize)]
struct Class {
class_number: u32,
students: Vec<Student>,
}
```
:::


**完成したら、以下のコマンドをターミナルで実行して上手く機能しているか確認しましょう。**
```bash
$ curl -X GET "http://localhost:8080/students/1/1" # pikachu
Expand All @@ -203,7 +207,7 @@ $ curl -X GET "http://localhost:8080/students/5/1" # Student Not Found
#!/bin/bash

# ↓これを自分のIDに変更してください
ID=pikachu
ID=kenken
# ↑これを自分のIDに変更してください

echo ""
Expand Down Expand Up @@ -273,7 +277,7 @@ echo ""
ペーストした後、ファイル内の以下の部分を自分の ID に書き換えてください。
```
# ↓これを自分のIDに変更してください
ID=pikachu
ID=kenken
# ↑これを自分のIDに変更してください
```

Expand All @@ -289,16 +293,15 @@ $ ./test.sh # シェルスクリプトtest.shを実行
$ ./test.sh

====================
[TEST] /pikachu
curl -X GET http://localhost:8080/pikachu
始めまして、@pikachuです
ケモノ(特に四足歩行)や、低頭身デフォルメマスコット(TDM)が大好きです
普段はVRChatに生息しています。twitter: @pikachu0310VRC
[TEST] /kenken
curl -X GET http://localhost:8080/kenken
始めまして、@kenkenです
きらら作品(特に恋する小惑星、スロウスタート)が好きです

====================
[TEST] /ping
curl -X GET http://localhost:8080/ping
pong

====================
[TEST] /fizzbuzz 1of3
-X GET http://localhost:8080/fizzbuzz?count=20
Expand Down Expand Up @@ -365,32 +368,31 @@ Bad Request
====================
[TEST] /add 1of4
curl -X POST http://localhost:8080/add -H "Content-Type: application/json" -d "{\"left\": 18781, \"right\": 18783}"
{"answer":37564}

{"result":37564}
====================
[TEST] /add 2of4
curl -X POST http://localhost:8080/add -H "Content-Type: application/json" -d "{\"left\": 0, \"right\": -0}"
{"answer":0}

{"result":0}
====================
[TEST] /add 3of4
curl -X POST http://localhost:8080/add -H "Content-Type: application/json" -d "{\"left\": a, \"right\": b}"
{"error":"Bad Request"}

====================
[TEST] /add 4of4
curl -X POST http://localhost:8080/add -H "Content-Type: application/json" -d "{\"left\": 100}"
{"error":"Bad Request"}

====================
[TEST] /students 1of2
[TEST] /students 1of3
curl -X GET http://localhost:8080/students/1/1
{"student_number":1,"name":"pikachu"}

====================
[TEST] /students 2of2
[TEST] /students 2of3
curl -X GET http://localhost:8080/students/3/4
{"error":"Student Not Found"}
{"error":"Student not found"}
====================
[TEST] /students 3of3
curl -X GET http://localhost:8080/students/5/1
{"error":"Student not found"}
```
:::

Expand Down
19 changes: 0 additions & 19 deletions docs/chapter1/section3/src/4-1_ping.go

This file was deleted.

22 changes: 22 additions & 0 deletions docs/chapter1/section3/src/4-1_ping.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use axum::{routing::get, Router};

#[tokio::main]
async fn main() {
// 「/ping」というエンドポイントを設定する
let app = Router::new().route("/ping", get(handler));

// ポート8080でリスナーを作成する
let listener = tokio::net::TcpListener::bind("127.0.0.1:8080")
.await
.unwrap();

println!("listening on {}", listener.local_addr().unwrap());

// サーバーを起動する
axum::serve(listener, app).await.unwrap();
}

// 文字列「pong」をクライアントに返す
async fn handler() -> String {
String::from("pong")
}
63 changes: 0 additions & 63 deletions docs/chapter1/section3/src/4-2_fizzbuzz.go

This file was deleted.

62 changes: 62 additions & 0 deletions docs/chapter1/section3/src/4-2_fizzbuzz.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use axum::{extract::Query, http::StatusCode, routing::get, Router};
#[tokio::main]
async fn main() {
// 「/ping」というエンドポイントを設定する
let app = Router::new().route("/fizzbuzz", get(fizzbuzz_handler));

// ポート8080でリスナーを作成する
let listener = tokio::net::TcpListener::bind("127.0.0.1:8080")
.await
.unwrap();

println!("listening on {}", listener.local_addr().unwrap());

// サーバーを起動する
axum::serve(listener, app).await.unwrap();
}

// クエリパラメータを受け取るための構造体を定義
#[derive(serde::Deserialize)]
struct FizzBuzzQuery {
count: Option<String>,
}

async fn fizzbuzz_handler(Query(query): Query<FizzBuzzQuery>) -> (StatusCode, String) {
// クエリパラメータが指定されていない場合はデフォルト値を使用する
let mut n: i32 = 30;
// クエリパラメータが指定されている場合はその値を調べる
if let Some(count) = query.count {
let count = count.parse();
match count {
// 数値に変換できた場合はその値を使用する
Ok(count) => n = count,
// ステータスコード 400 Bad Request を返す
Err(_) => return (StatusCode::BAD_REQUEST, String::from("Bad Request\n")),
}
}

// FizzBuzzの処理をする
let fizzbuzz_str = fizzbuzz(n);

// ステータスコード 200 Ok とfizzBuzzの結果を返す
(StatusCode::OK, fizzbuzz_str + "\n")
}

// fizzBuzzの処理
fn fizzbuzz(n: i32) -> String {
let mut result = String::new();
for i in 1..=n {
if i % 15 == 0 {
result.push_str("FizzBuzz\n");
} else if i % 3 == 0 {
result.push_str("Fizz\n");
} else if i % 5 == 0 {
result.push_str("Buzz\n");
} else {
result.push_str(&i.to_string());
result.push('\n');
}
}
result
}

50 changes: 0 additions & 50 deletions docs/chapter1/section3/src/4-3_add.go

This file was deleted.

Loading
Loading