INTEGRITY Dokumentace

Použijte Workers KV přímo z Rustu

Tento návod vás naučí, jak přímo z Rustu číst a zapisovat do KV pomocí workers-rs.

Než začnete

Všechny návody předpokládají, že jste již dokončili Úvodní návod, který vás provede nastavením účtu Cloudflare Workers, C3, a Wrangler.

Předpoklady

Pro dokončení tohoto tutoriálu budete potřebovat:

cargo install cargo-generate

1. Vytvořte projekt Worker v Rustu

Otevřete okno terminálu a spuštěním následujícího příkazu vygenerujte šablonu projektu Workeru v Rustu:

cargo generate cloudflare/workers-rs

Poté vyberte template/hello-world-http šablonu, zadejte projektu výstižný název a stiskněte enter. Ve vašem adresáři by se měl vytvořit nový projekt. Otevřete projekt ve svém editoru a spusťte npx wrangler dev pro kompilaci a spuštění vašeho projektu.

V tomto tutoriálu použijete Workers KV z Rustu k sestavení aplikace, která ukládá a načítá města podle zadaného názvu země.

2. Vytvořte KV namespace

V terminálu použijte Wrangler k vytvoření KV namespace pro cities. Tím se vygeneruje konfigurace, kterou přidáte do projektu:

npx wrangler kv namespace create cities

Chcete-li tuto konfiguraci přidat do projektu, otevřete soubor Wrangler a vytvořte položku pro kv_namespaces nad příkazem sestavení:

{
	"kv_namespaces": [
		{
			"binding": "cities",
			"id": "e29b263ab50e42ce9b637fa8370175e8"
		}
	]
}
[[kv_namespaces]]
binding = "cities"
id = "e29b263ab50e42ce9b637fa8370175e8"

Po tomto nastavení můžete přistupovat k KV namespace pomocí bindingu "cities" z Rustu.

3. Zapište data do KV

Pro tuto aplikaci vytvoříte dvě routes: POST trasu pro příjem a uložení města do KV a GET trasu pro načtení města dané země. Například POST požadavek na /France s tělem {"city": "Paris"} by mělo vytvořit záznam Paříže jako města ve Francii. GET požadavek na /France by měl načíst z KV a odpovědět Paříží.

Nainstalujte Serde jako závislost projektu pro zpracování JSON cargo add serde. Poté vytvořte app router a strukturu pro Country v src/lib.rs:

use serde::{Deserialize, Serialize};
use worker::*;

#[event(fetch)]
async fn fetch(req: Request, env: Env, _ctx: Context) -> Result<Response> {
    let router = Router::new();

    #[derive(Serialize, Deserialize, Debug)]
    struct Country {
        city: String,
    }

    router
        // TODO:
        .post_async("/:country", |_, _| async move { Response::empty() })
        // TODO:
        .get_async("/:country", |_, _| async move { Response::empty() })
        .run(req, env)
        .await
}

V post handleru získáte název země z cesty a název města z těla požadavku. Poté je uložíte do KV, kde zemi použijete jako klíč a město jako hodnotu. Nakonec aplikace odpoví názvem města:

.post_async("/:country", |mut req, ctx| async move {
    let country = ctx.param("country").unwrap();
    let city = match req.json::<Country>().await {
        Ok(c) => c.city,
        Err(_) => String::from(""),
    };
    if city.is_empty() {
        return Response::error("Bad Request", 400);
    };
    return match ctx.kv("cities")?.put(country, &city)?.execute().await {
        Ok(_) => Response::ok(city),
        Err(_) => Response::error("Bad Request", 400),
    };
})

Uložte soubor a vytvořte POST požadavek pro otestování tohoto endpointu:

curl --json '{"city": "Paris"}' http://localhost:8787/France

4. Načtěte data z KV

Chcete-li načíst města uložená v KV, napište GET trasa, která načte název země z cesty a vyhledá ji v KV. Potřebujete také ošetřit chybu pro případ, že země nebude nalezena:

.get_async("/:country", |_req, ctx| async move {
    if let Some(country) = ctx.param("country") {
        return match ctx.kv("cities")?.get(country).text().await? {
            Some(city) => Response::ok(city),
            None => Response::error("Country not found", 404),
        };
    }
    Response::error("Bad Request", 400)
})

Uložte a otestujte koncový bod pomocí požadavku curl:

curl http://localhost:8787/France

5. Nasaďte svůj projekt

Zdrojový kód dokončené aplikace by měl obsahovat následující:

use serde::{Deserialize, Serialize};
use worker::*;

#[event(fetch)]
async fn fetch(req: Request, env: Env, _ctx: Context) -> Result<Response> {
    let router = Router::new();

    #[derive(Serialize, Deserialize, Debug)]
    struct Country {
        city: String,
    }

    router
        .post_async("/:country", |mut req, ctx| async move {
            let country = ctx.param("country").unwrap();
            let city = match req.json::<Country>().await {
                Ok(c) => c.city,
                Err(_) => String::from(""),
            };
            if city.is_empty() {
                return Response::error("Bad Request", 400);
            };
            return match ctx.kv("cities")?.put(country, &city)?.execute().await {
                Ok(_) => Response::ok(city),
                Err(_) => Response::error("Bad Request", 400),
            };
        })
        .get_async("/:country", |_req, ctx| async move {
            if let Some(country) = ctx.param("country") {
                return match ctx.kv("cities")?.get(country).text().await? {
                    Some(city) => Response::ok(city),
                    None => Response::error("Country not found", 404),
                };
            }
            Response::error("Bad Request", 400)
        })
        .run(req, env)
        .await
}

Chcete-li nasadit svůj Worker, spusťte následující příkaz:

npx wrangler deploy