その他

【Rust】RocketでAPIモックを作ってみた

その他
この記事は約5分で読めます。

※ 初心者記事です

Rocketとは

Rocketは、Rustで記述されたWebフレームワークです。
https://rocket.rs/

作るもの

練習として、簡単なJSONを返すAPIモックを作成します。

動画の一覧を返す想定です。

依存関係

[package]
version = "0.1.0"
edition = "2018"

[dependencies]
rocket = "0.4.6"
serde = { version = "^1.0.101", features = ["derive"] }
serde_json = "^1.0.41"

[dependencies.rocket_contrib]
version = "0.4.6"
default-features = false
features = ["json"]

構造体の定義

動画です。

models.rs

pub struct Video {
  pub id: u32,
  pub title: String,
  pub description: String,
}

impl Video {
  pub fn new(id: u32, title: &str, description: &str) -> Self {
    Self {
      id,
      title: title.to_string(),
      description: description.to_string(),
    }
  }
}

Serde

Serdeというクレートを使用することで、構造体⇄JSONへのシリアライズ/デシリアライズが簡単にできます。

models.rs

use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
pub struct Video {
  pub id: u32,
  pub title: String,
  pub description: String,
}

ルーティング

簡単設計。GET /videosに対してJSONを返す。

route.rs

use rocket_contrib::json;
use rocket_contrib::json::{JsonValue};

use crate::models::Video;

#[get("/")]
pub fn index() -> &'static str {
    "Hello, world!"
}

/// Jsonの型がResponderをimplしているので、JSON文字列を返すことができる
#[get("/videos")]
pub fn videos() -> JsonValue {
    let video1: Video = Video::new(1, "ビデオ1", "あああ");
    let video2: Video = Video::new(2, "ビデオ2", "いいい");
    let video3: Video = Video::new(3, "ビデオ3", "ううう");
    let videos:[Video; 3] = [video1, video2, video3];
    json!(videos)
}

サーバ起動

もろもろインポートして起動する

main.rs

#![feature(proc_macro_hygiene, decl_macro)]
#[macro_use] extern crate rocket;

mod models;
mod routes;
use routes::*;

fn main() {
    rocket::ignite().mount("/", routes![index, videos]).launch();
}

CORSの設定

CORSを許可する

cors.rs

use rocket::{Request, Response};
use rocket::fairing::{Fairing, Info, Kind};
use rocket::http::Header;

pub struct CORS();

impl Fairing for CORS {
    fn info(&self) -> Info {
        Info {
            name: "Add CORS headers to requests",
            kind: Kind::Response
        }
    }

    fn on_response(&self, request: &Request, response: &mut Response) {
        response.set_header(Header::new("Access-Control-Allow-Origin", "*"));
        response.set_header(Header::new("Access-Control-Allow-Methods", "POST, GET, PATCH, OPTIONS"));
        response.set_header(Header::new("Access-Control-Allow-Headers", "*"));
        response.set_header(Header::new("Access-Control-Allow-Credentials", "true"));
    }
}

rocketサーバに差し込む

main.rs

...
mod cors;
use cors::CORS;

fn main() {
    rocket::ignite().attach(CORS()).mount("/", routes![index, videos]).launch();
}

まとめ

Rust初心者でもドキュメント通りやれば作れる。
性能も折り紙付らしい。