paradox-gloo-net
Usage
paradox-gloo-net --uri createUser --uri getUser
All flags:
| Flag | Default | Description |
|---|---|---|
|
(required, repeatable) |
Name of a spec constant that evaluates to a URI or a product of URIs |
|
|
Base path prepended to all generated URLs |
|
|
Output file path for the generated client module |
The --uri flag can be repeated to include endpoints from multiple constants:
paradox-gloo-net --uri publicApi --uri adminApi --base-path "/api/v1"
Example
Given this .dox specification:
import std
type User
id: Text
name: Text
email: Text
type CreateUserRequest
name: Text
email: Text
createUser: URI
http://localhost/users POST (CreateUserRequest. User)
getUser: URI
http://localhost/users/${Integer id} GET (Unit. User)
listUsers: URI
http://localhost/users GET (Unit. [User])
Run:
paradox-gloo-net --uri createUser --uri getUser --uri listUsers
This generates .dox/client.rs:
//! Generated by paradox-gloo-net — do not edit
use gloo_net::http::Request;
use crate::{
CreateUserRequest,
User
};
const API_BASE: &str = "";
pub async fn create_user(input: &CreateUserRequest) -> Result<User, String> {
let url = format!("{}/users", API_BASE);
let response = Request::post(&url)
.header("Content-Type", "application/json")
.body(serde_json::to_string(input).map_err(|e| e.to_string())?)
.map_err(|e| e.to_string())?
.send()
.await
.map_err(|e| e.to_string())?;
if !response.ok() {
return Err(format!("HTTP error: {}", response.status()));
}
response
.json::<User>()
.await
.map_err(|e| e.to_string())
}
pub async fn get_user(id: i64) -> Result<User, String> {
let url = format!("{}/users/{}", API_BASE, id);
let response = Request::get(&url)
.send()
.await
.map_err(|e| e.to_string())?;
if !response.ok() {
return Err(format!("HTTP error: {}", response.status()));
}
response
.json::<User>()
.await
.map_err(|e| e.to_string())
}
pub async fn list_users() -> Result<Vec<User>, String> {
let url = format!("{}/users", API_BASE);
let response = Request::get(&url)
.send()
.await
.map_err(|e| e.to_string())?;
if !response.ok() {
return Err(format!("HTTP error: {}", response.status()));
}
response
.json::<Vec<User>>()
.await
.map_err(|e| e.to_string())
}
Wiring It Up
mod client;
use client::{create_user, get_user, list_users};
use crate::CreateUserRequest;
async fn example() -> Result<(), String> {
let new_user = CreateUserRequest {
name: "Isaac".into(),
email: "isaac@example.com".into(),
};
let user = create_user(&new_user).await?;
let fetched = get_user(1).await?;
let all = list_users().await?;
Ok(())
}
How It Works
paradox-gloo-net operates in three stages:
-
Evaluate URIs to JSON — For each
--uriname, runsparadox generate --json <name>to get the structured URI data -
Parse URI configs — Extracts
path,meta(HTTP method), andio(input/output types) from each URI -
Generate client module — Produces a Rust module with one
pub async fnper endpoint
URI Constants vs Products of URIs
The --uri flag accepts either a single URI constant or a product type whose fields are URIs:
| Single URI -- pass as --uri createUser
createUser: URI
http://localhost/users POST (CreateUserRequest. User)
| Product of URIs -- pass as --uri api
type ApiEndpoints
createUser: URI
getUser: URI
api: ApiEndpoints
ApiEndpoints:
createUser: http://localhost/users POST (CreateUserRequest. User)
getUser: http://localhost/users/${Integer id} GET (Unit. User)
Path Parameters
Interpolated type captures in URI paths are converted to function parameters:
.dox Path |
Parameter | Rust Type |
|---|---|---|
|
|
|
|
|
|
|
|
|
Type Mapping
Paradox types are mapped to Rust types:
| Paradox Type | Rust Type |
|---|---|
|
|
|
|
|
|
|
|
Other |
Used as-is (e.g., |
Request Bodies
POST, PUT, and PATCH endpoints with a non-unit input type serialize the input with serde_json and set Content-Type: application/json.
See Also
-
URI Types — URI literal syntax and structure
-
Rust Code Generation — Generate the types module that the client imports
-
paradox-express — Express.js server equivalent
-
paradox-servant — Haskell Servant equivalent