Skip to content

JSONレスポンスを返してみよう

先ほど作ったmain.goに、レスポンスとして JSON を返すエンドポイントを追加しましょう。

TIP

JSON について分からない人は JSONってなにもの? | Think IT(シンクイット)

TIP

Rust の構造体についてわからない人は↓を見ると良いです。

https://doc.rust-jp.rs/book-ja/ch05-01-defining-structs.html

JSON をレスポンスとして返すためには、Json に構造体を渡します。
先ほどの章で作成したmain.rsに、以下のようなエンドポイントを追加して、JSONレスポンスを返してみましょう。

rs
use axum::{routing::get, Json, Router};

#[tokio::main]
async fn main() {
	// 「/json」というパスのエンドポイントを定義
    let app = Router::new()
        .route("/json", get(json_handler));

	// Webサーバーをポート番号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();
}

// JSONで返すための構造体を定義
// 構造体を JSON に変換するためにserde::Serializeトレイトを導出する
#[derive(serde::Serialize)]
struct JsonData {
    number: i32,
    string: String,
    bool: bool,
}

async fn json_handler() -> Json<JsonData> {
	// レスポンスとして返す値を構造体として定義
    let res = JsonData {
        number: 10,
        string: String::from("hoge"),
        bool: false,
    };

	// 構造体をJSONに変換してクライアントに返す
    Json(res)
}

書き換えたら、localhost:8080/json にアクセスして確認してみましょう。

Postmanでリクエストしてみよう

Postman を起動したら、workspace を作成して移動し、Ctrl + N->HTTPまたはOverviewタブの横にある+を押して、リクエスト設定画面を開きます。

Enter URL or paste textとあるところで HTTP method と URL を指定できます。
Postman を使って、GET リクエストを自分のサーバーに送ってみましょう。 つまり、HTTP MethodとしてGETを使用して、URLhttp://localhost:8080/helloにリクエストを送信しましょう。

HTTP Method: GET

URL: http://localhost:8080/hello

以下の画像のように設定してください。

Hello, World.

と表示されれば成功です。

次に POST リクエストを使ってみましょう

POST ではサーバーにデータを送ることができます。

  1. Postman で Body タブを選択
  2. ラジオボタンのrawを選択
  3. 右に出てくるプルダウンからJSON(application/json)を選択します
    POST で渡せるデータの型は複数あり、上記の操作で JSON を使うということを明示しています。

以下のように自分の traQ ID を POST してみましょう。

HTTP method: POST

URL: https://eo6mn2b7rlihmgg.m.pipedream.net
json
{
    "traq_id": "pikachu"
}

traq_idpikachuの例だと、上の画像のように、以下のような JSON が返ってきます。

{
    ...
    "body": {
        "traq_id": "pikachu"
    }
}

自分のサーバーでPOSTを受け取ってみよう

POST で JSON を受け取って、内容をそのまま返すサーバーを作ってみます。
get()と同じように、post()と書くことで POST を受け取ることができます。
POST のハンドラでは Result 型を受け取っています。 パースに成功した場合は、match の中の Ok に入り、失敗した場合は Err に入ります。

rs
use core::fmt;

use axum::{
    extract::rejection::JsonRejection,
    http::StatusCode,
    routing::{get, post},
    Json, Router,
};

#[tokio::main]
async fn main() {
    // post() メソッドを使ってPOSTリクエストを処理する
    let app = Router::new()
        .route("/post", post(post_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();
}

// JSONを受け取るための構造体を定義
// 構造体を JSON に変換するためにserde::Serializeを導出する
#[derive(serde::Deserialize, serde::Serialize)]
struct JsonData {
    number: i32,
    string: String,
    bool: bool,
}

async fn post_handler(
    query: Result<Json<JsonData>, JsonRejection>,
) -> Result<Json<JsonData>, (StatusCode, JsonRejection)> {
    match query {
        // 正常なときリクエストデータをそのまま返す
        Ok(data) => Ok(data),
        // 正常でないときステータスコード 400 Bad Requestを返す
        Err(rejection) => Err((StatusCode::BAD_REQUEST, rejection)),
    }
}

Postman を使って実際に受け取れている / 送り返せているか確認してみましょう。