farp

Crates.iofarp
lib.rsfarp
version1.0.2
created_at2025-11-05 22:55:59.26402+00
updated_at2025-12-08 14:54:17.116681+00
descriptionForge API Gateway Registration Protocol (FARP) - Schema-aware service discovery and gateway integration
homepage
repositoryhttps://github.com/xraph/farp
max_upload_size
id1918770
size333,883
Rex Raphael (juicycleff)

documentation

https://docs.rs/farp

README

FARP - Forge API Gateway Registration Protocol

License Rust

FARP is a Rust implementation of the Forge API Gateway Registration Protocol - a standardized mechanism for service instances to register their API schemas, health information, and capabilities with API gateways and service discovery systems.

๐ŸŒŸ Features

  • Schema-Aware Discovery: Extend service discovery with API contract information
  • Multi-Protocol Support: REST (OpenAPI), AsyncAPI, gRPC, GraphQL, oRPC, Avro, and Thrift
  • Gateway Automation: Enable API gateways to auto-configure routes from schemas
  • Backend Agnostic: Work with any service discovery backend (in-memory registry included)
  • Type-Safe: Fully typed with comprehensive error handling
  • Async First: Built on tokio for high-performance async I/O
  • Zero-Downtime Updates: Support for schema versioning and compatibility checks
  • Production Ready: Checksums, validation, compression, and observability built-in

๐Ÿ“ฆ Installation

Add FARP to your Cargo.toml:

[dependencies]
farp = "1.0.0"

# With all features
farp = { version = "1.0.0", features = ["full"] }

# With specific providers
farp = { version = "1.0.0", features = ["providers-openapi", "providers-asyncapi", "gateway"] }

๐Ÿš€ Quick Start

use farp::prelude::*;
use std::sync::Arc;

#[tokio::main]
async fn main() -> Result<()> {
    // 1. Create a schema manifest
    let mut manifest = new_manifest("user-service", "v1.0.0", "instance-123");
    manifest.add_capability("rest");
    manifest.endpoints.health = "/health".to_string();

    // 2. Add an OpenAPI schema
    let schema = serde_json::json!({
        "openapi": "3.1.0",
        "info": {"title": "User API", "version": "1.0.0"},
        "paths": {"/users": {"get": {}}}
    });

    let hash = calculate_schema_checksum(&schema)?;
    manifest.add_schema(SchemaDescriptor {
        schema_type: SchemaType::OpenAPI,
        spec_version: "3.1.0".to_string(),
        location: SchemaLocation {
            location_type: LocationType::Inline,
            inline_schema: Some(schema),
            ..Default::default()
        },
        hash,
        content_type: "application/json".to_string(),
        size: 1024,
        ..Default::default()
    });

    manifest.update_checksum()?;
    manifest.validate()?;

    // 3. Register with an in-memory registry
    use farp::registry::memory::MemoryRegistry;
    let registry = Arc::new(MemoryRegistry::new());
    registry.register_manifest(&manifest).await?;

    println!("โœ… Manifest registered successfully!");
    Ok(())
}

๐ŸŽฏ Feature Flags

FARP uses feature flags to minimize dependencies:

  • default: Core types + memory registry
  • memory-registry: In-memory registry implementation
  • providers-openapi: OpenAPI schema provider
  • providers-asyncapi: AsyncAPI schema provider
  • providers-grpc: gRPC/Protocol Buffer provider
  • providers-graphql: GraphQL schema provider
  • providers-orpc: oRPC provider
  • providers-avro: Apache Avro provider
  • providers-thrift: Apache Thrift provider
  • providers-all: All schema providers
  • gateway: Gateway client for route conversion
  • full: Everything enabled

๐Ÿ“š Core Concepts

Schema Manifest

A Schema Manifest describes all API contracts exposed by a service instance:

pub struct SchemaManifest {
    pub version: String,              // Protocol version
    pub service_name: String,         // Service name
    pub service_version: String,      // Service version
    pub instance_id: String,          // Instance ID
    pub schemas: Vec<SchemaDescriptor>, // API schemas
    pub capabilities: Vec<String>,    // Protocols supported
    pub endpoints: SchemaEndpoints,   // Health/metrics endpoints
    pub updated_at: i64,              // Unix timestamp
    pub checksum: String,             // SHA256 of schemas
}

Schema Descriptor

A Schema Descriptor describes a single API schema:

pub struct SchemaDescriptor {
    pub schema_type: SchemaType,      // OpenAPI, AsyncAPI, etc.
    pub spec_version: String,         // Spec version
    pub location: SchemaLocation,     // Where to fetch schema
    pub content_type: String,         // MIME type
    pub hash: String,                 // SHA256 hash
    pub size: i64,                    // Size in bytes
}

Location Strategies

Schemas can be retrieved via three strategies:

  • HTTP: Gateway fetches from service HTTP endpoint
  • Registry: Gateway fetches from backend KV store
  • Inline: Schema embedded directly in manifest

๐Ÿ”ง Usage Examples

Create and Register a Manifest

use farp::prelude::*;

let mut manifest = new_manifest("api-service", "v1.0.0", "instance-1");
manifest.add_capability("rest");
manifest.endpoints.health = "/health".to_string();
manifest.update_checksum()?;

// Register with registry
registry.register_manifest(&manifest).await?;

Watch for Schema Changes

use farp::prelude::*;

registry.watch_manifests("api-service", Box::new(|event| {
    match event.event_type {
        EventType::Added => println!("Service added: {}", event.manifest.instance_id),
        EventType::Updated => println!("Service updated: {}", event.manifest.instance_id),
        EventType::Removed => println!("Service removed: {}", event.manifest.instance_id),
    }
})).await?;

Gateway Integration

use farp::gateway::Client;

let client = Client::new(registry);

client.watch_services("api-service", |routes| {
    for route in routes {
        println!("Configure route: {} {} -> {}",
            route.methods.join(","),
            route.path,
            route.target_url
        );
    }
}).await?;

Schema Providers

use farp::providers::openapi::OpenAPIProvider;
use farp::provider::{SchemaProvider, Application};

struct MyApp;

impl Application for MyApp {
    fn name(&self) -> &str { "my-app" }
    fn version(&self) -> &str { "1.0.0" }
    fn routes(&self) -> Box<dyn std::any::Any + Send + Sync> {
        Box::new(()) // Your route info
    }
}

let provider = OpenAPIProvider::default();
let schema = provider.generate(&MyApp).await?;

๐Ÿงช Testing

Run the test suite:

# Run all tests
cargo test

# Run tests with all features
cargo test --all-features

# Run specific test
cargo test test_manifest_creation

# Run with output
cargo test -- --nocapture

Run the example:

cargo run --example basic --all-features

๐Ÿ“– Documentation

Generate and view documentation:

cargo doc --all-features --open

๐Ÿ—๏ธ Architecture

FARP follows a layered architecture:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚     Applications & Gateways          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
              โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚        FARP Protocol Core            โ”‚
โ”‚  - Types & Manifests                 โ”‚
โ”‚  - Provider & Registry Traits        โ”‚
โ”‚  - Validation & Checksums            โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
              โ”‚
        โ”Œโ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ”‚            โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Providers   โ”‚  โ”‚  Registries      โ”‚
โ”‚  - OpenAPI   โ”‚  โ”‚  - Memory        โ”‚
โ”‚  - AsyncAPI  โ”‚  โ”‚  - (Future: etcd,โ”‚
โ”‚  - gRPC      โ”‚  โ”‚    Consul, K8s)  โ”‚
โ”‚  - GraphQL   โ”‚  โ”‚                  โ”‚
โ”‚  - ...       โ”‚  โ”‚                  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿค Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

๐Ÿ“„ License

Licensed under either of:

at your option.

๐Ÿ”— Related Projects

๐Ÿ“ฌ Contact

For questions or feedback, please open an issue.


Built with โค๏ธ using Rust

Commit count: 0

cargo fmt