Module chapter_4

Module chapter_4 

Source
Expand description

§Chapter 4: Advanced Parameters

This chapter covers headers, cookies, and advanced parameter serialization styles.

§Header Parameters

Use CallHeaders to add request headers:

use clawspec_core::{ApiClient, CallHeaders};

let headers = CallHeaders::new()
    .add_header("X-Request-ID", "req-12345")
    .add_header("X-Client-Version", "1.0.0")
    .add_header("Accept-Language", "en-US");

let response: Response = client
    .get("/data")?
    .with_headers(headers)
    .await?
    .as_json()
    .await?;

Headers are documented in the OpenAPI specification as header parameters.

Use CallCookies for cookie-based parameters:

use clawspec_core::{ApiClient, CallCookies};

let cookies = CallCookies::new()
    .add_cookie("session_id", "abc123")
    .add_cookie("user_id", 42)
    .add_cookie("preferences", vec!["dark_mode", "compact"]);

let profile: Profile = client
    .get("/profile")?
    .with_cookies(cookies)
    .await?
    .as_json()
    .await?;

§Authentication

Clawspec supports several authentication methods:

use clawspec_core::{ApiClient, Authentication};

// Bearer token (most common for APIs)
let client = ApiClient::builder()
    .with_host("api.example.com")
    .with_authentication(Authentication::Bearer("your-api-token".into()))
    .build()?;

// Basic authentication
let client = ApiClient::builder()
    .with_host("api.example.com")
    .with_authentication(Authentication::Basic {
        username: "user".to_string(),
        password: "secret".into(),
    })
    .build()?;

// API key in header
let client = ApiClient::builder()
    .with_host("api.example.com")
    .with_authentication(Authentication::ApiKey {
        header_name: "X-API-Key".to_string(),
        key: "your-api-key".into(),
    })
    .build()?;

You can override authentication per-request:

let mut client = ApiClient::builder()
    .with_host("api.example.com")
    .with_authentication(Authentication::Bearer("default-token".into()))
    .build()?;

// Use different auth for admin endpoints
client.get("/admin/users")?
    .with_authentication(Authentication::Bearer("admin-token".into()))
    .await?;

// Remove auth for public endpoints
client.get("/public/status")?
    .with_authentication_none()
    .await?;

§Parameter Styles

OpenAPI defines various serialization styles for parameters. Use ParamStyle:

§Path Parameter Styles

use clawspec_core::{CallPath, ParamValue, ParamStyle};

// Simple (default): /users/123
let path = CallPath::from("/users/{id}")
    .add_param("id", ParamValue::new(123));

// Label style: /users/.123
let path = CallPath::from("/users/{id}")
    .add_param("id", ParamValue::with_style(123, ParamStyle::Label));

// Matrix style: /users/;id=123
let path = CallPath::from("/users/{id}")
    .add_param("id", ParamValue::with_style(123, ParamStyle::Matrix));

§Query Parameter Styles

use clawspec_core::{CallQuery, ParamValue, ParamStyle};

let tags = vec!["rust", "web", "api"];

// Form (default): ?tags=rust&tags=web&tags=api
let query = CallQuery::new()
    .add_param("tags", ParamValue::new(tags.clone()));

// Space delimited: ?tags=rust%20web%20api
let query = CallQuery::new()
    .add_param("tags", ParamValue::with_style(tags.clone(), ParamStyle::SpaceDelimited));

// Pipe delimited: ?tags=rust|web|api
let query = CallQuery::new()
    .add_param("tags", ParamValue::with_style(tags, ParamStyle::PipeDelimited));

§Deep Object Style

For nested objects in query parameters:

use clawspec_core::{CallQuery, ParamValue, ParamStyle};

// Deep object: ?filter[status]=active&filter[type]=premium
let filter = serde_json::json!({
    "status": "active",
    "type": "premium"
});

let query = CallQuery::new()
    .add_param("filter", ParamValue::with_style(filter, ParamStyle::DeepObject));

§Alternative Content Types

Besides JSON, you can send other content types:

use clawspec_core::ApiClient;
use headers::ContentType;

#[derive(Serialize, ToSchema)]
struct FormData {
    name: String,
    email: String,
}

// Form-encoded data
let data = FormData {
    name: "Alice".to_string(),
    email: "alice@example.com".to_string(),
};
client.post("/form")?.form(&data)?.await?;

// Raw bytes with custom content type
let xml = r#"<user><name>Alice</name></user>"#;
client.post("/xml")?
    .raw(xml.as_bytes().to_vec(), ContentType::xml())
    .await?;

// Multipart form data
let files = vec![
    ("file1", r#"{"data": "content1"}"#),
    ("file2", r#"{"data": "content2"}"#),
];
client.post("/upload")?.multipart(files).await?;

§Key Points

  • CallHeaders and CallCookies add documented parameters
  • Authentication can be set at client or request level
  • Parameter styles control OpenAPI serialization documentation
  • Multiple content types are supported (JSON, form, XML, multipart)

Next: Chapter 5: OpenAPI Customization - Tags, descriptions, and metadata.