From a4f6c82ef1f4bdd4c00ab235c4852398d456797e Mon Sep 17 00:00:00 2001 From: kenken714 Date: Mon, 11 Nov 2024 18:42:18 +0900 Subject: [PATCH 1/2] feat: add main.rs --- docs/chapter2/section4/1_image.md | 24 +++++++++-------------- docs/chapter2/section4/src/main.go | 31 ------------------------------ docs/chapter2/section4/src/main.rs | 25 ++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 46 deletions(-) delete mode 100644 docs/chapter2/section4/src/main.go create mode 100644 docs/chapter2/section4/src/main.rs diff --git a/docs/chapter2/section4/1_image.md b/docs/chapter2/section4/1_image.md index e1bc9531..17e2c4a9 100644 --- a/docs/chapter2/section4/1_image.md +++ b/docs/chapter2/section4/1_image.md @@ -4,36 +4,30 @@ ### コードを書く -`naro_server`というディレクトリを作り、その中でコードを書いてください。第 1 部でやったように、 Go を使って下の条件を満たすサーバーアプリケーションを作ってください。 +`naro_server`というディレクトリを作り、その中でコードを書いてください。第 1 部でやったように、 Rust を使って下の条件を満たすサーバーアプリケーションを作ってください。 - `/greeting`への GET リクエストに、環境変数 `GREETING_MESSAGE`の値を返す。 - 起動するポートを環境変数`PORT`で指定できる。 -`go mod`コマンドで外部ライブラリを管理しましょう。 - -https://go.dev/ref/mod - -```sh -go mod init naro_server -go mod tidy -``` - :::details 答え -<<< @/chapter2/section4/src/main.go +<<< @/chapter2/section4/src/main.rs + +※ `axum` や `tokio` の依存関係を追加する必要があります。 ::: ### ビルドして実行する -今までは`go run`コマンドでプログラムを実行していましたが、Go では`go build`コマンドでコンパイルして実行ファイルを生成し、そのファイルを用いてプログラムを実行できます。 +今までは`cargo run`コマンドでプログラムを実行していましたが、Rust では`cargo build`コマンドでコンパイルして実行ファイルを生成し、そのファイルを用いてプログラムを実行できます。 ```sh -go build -o server +cargo build --release ``` -上のコマンドを実行すると`server`というファイルが生成され、`./server`で実行できます。 +`--release`オプションをつけることで、最適化されたバイナリが生成されます。 +以下のコマンドで実行できます。 ```sh -GREETING_MESSAGE="こんにちは" PORT="8080" ./server +GREETING_MESSAGE="こんにちは" PORT="8080" ./target/release/naro-server ``` 実行前に環境変数を設定しています。 diff --git a/docs/chapter2/section4/src/main.go b/docs/chapter2/section4/src/main.go deleted file mode 100644 index 673ab259..00000000 --- a/docs/chapter2/section4/src/main.go +++ /dev/null @@ -1,31 +0,0 @@ -package main - -import ( - "log" - "net/http" - "os" - - "github.com/labstack/echo/v4" -) - -func main() { - port, ok := os.LookupEnv("PORT") - if !ok { - log.Fatal("failed to get env PORT") - } - - e := echo.New() - - e.GET("/greeting", greetingHandler) - - e.Logger.Fatal(e.Start(":" + port)) -} - -func greetingHandler(c echo.Context) error { - greeting, ok := os.LookupEnv("GREETING_MESSAGE") - if !ok { - return echo.NewHTTPError(http.StatusInternalServerError, "failed to get env GREETING_MESSAGE") - } - - return c.String(http.StatusOK, greeting) -} diff --git a/docs/chapter2/section4/src/main.rs b/docs/chapter2/section4/src/main.rs new file mode 100644 index 00000000..70341915 --- /dev/null +++ b/docs/chapter2/section4/src/main.rs @@ -0,0 +1,25 @@ +use axum::{http::StatusCode, routing::get, Router}; + +#[tokio::main] +async fn main() { + let port = std::env::var("PORT") + .expect("failed to get env PORT") + .parse::() + .expect("failed to parse PORT"); + + let app = Router::new().route("/greeting", get(greeting_handler)); + + let addr = std::net::SocketAddr::from(([127, 0, 0, 1], port)); + + let listener = tokio::net::TcpListener::bind(&addr).await.unwrap(); + + println!("Listening on {}", addr); + + axum::serve(listener, app).await.unwrap(); +} + +async fn greeting_handler() -> Result<(StatusCode, String), StatusCode> { + let greeting = + std::env::var("GREETING_MESSAGE").map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; + Ok((StatusCode::OK, greeting)) +} From 7b791ced38e8f80d15022914b20ead6442531701 Mon Sep 17 00:00:00 2001 From: kenken714 Date: Mon, 11 Nov 2024 19:12:30 +0900 Subject: [PATCH 2/2] feat: Dockerfile --- docs/chapter2/section4/1_image.md | 14 ++++++++------ docs/chapter2/section4/src/main.rs | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/chapter2/section4/1_image.md b/docs/chapter2/section4/1_image.md index 17e2c4a9..057516a8 100644 --- a/docs/chapter2/section4/1_image.md +++ b/docs/chapter2/section4/1_image.md @@ -9,6 +9,8 @@ - `/greeting`への GET リクエストに、環境変数 `GREETING_MESSAGE`の値を返す。 - 起動するポートを環境変数`PORT`で指定できる。 +ただし、 listen する IP アドレスとして、**必ず `0.0.0.0` を指定してください。** + :::details 答え <<< @/chapter2/section4/src/main.rs @@ -51,11 +53,11 @@ Dockerfile を書くと自分で必要な機能がそろったコンテナを立 ただ、アプリケーションを動かすだけであれば一度書いた Dockerfile を使いまわすことも可能なので、テンプレートを探してきてそれを使っても構いません。 -以下が Go のプログラムを動かすための最小の Dockerfile です。 +以下が Rust のプログラムを動かすための最小の Dockerfile です。 ```Dockerfile -# Go のベースイメージを指定 -FROM golang:1.20.5-alpine +# Rust のベースイメージを指定 +FROM rust:latest # コマンドを実行するコンテナ内のディレクトリをworkに指定 WORKDIR /work @@ -63,11 +65,11 @@ WORKDIR /work # ローカルのカレントディレクトリをコンテナのカレントディレクトリ(work)にコピー COPY . . -# Go のプログラムをビルド -RUN go build -o app +# Rust のプログラムをビルド +RUN cargo build --release # ビルドしたものを実行 -ENTRYPOINT ./app +ENTRYPOINT ["./target/release/naro-server"] ``` naro_server ディレクトリ内に`Dockerfile`というファイルを作り、上のコードを書きましょう。 diff --git a/docs/chapter2/section4/src/main.rs b/docs/chapter2/section4/src/main.rs index 70341915..b5bdd89b 100644 --- a/docs/chapter2/section4/src/main.rs +++ b/docs/chapter2/section4/src/main.rs @@ -9,7 +9,7 @@ async fn main() { let app = Router::new().route("/greeting", get(greeting_handler)); - let addr = std::net::SocketAddr::from(([127, 0, 0, 1], port)); + let addr = std::net::SocketAddr::from(([0, 0, 0, 0], port)); let listener = tokio::net::TcpListener::bind(&addr).await.unwrap();