FTL SDK Rust Macros
Procedural macros for reducing boilerplate in FTL tool components written in Rust.
Overview
This crate provides the #[tool]
attribute macro for creating tool handler functions with minimal boilerplate. The macro:
- Automatically derives JSON schemas from your input types (requires
JsonSchema
derive) - Supports both synchronous and asynchronous functions
- Generates the complete HTTP handler with metadata
- Handles all the boilerplate for you
Usage
Basic Tool Handler
The #[tool]
macro simplifies creating tool handlers:
use tool;
use ;
use Deserialize;
use JsonSchema;
/// Echoes back the input message
Complete Example
Here's a more complete example showing how the macro works with complex input types:
use tool;
use ToolResponse;
use Deserialize;
use JsonSchema;
/// Performs basic arithmetic operations
// The macro generates the HTTP handler automatically!
Generated Code
The #[tool]
macro generates:
- A
handle_tool_component
async function that returns metadata on GET and executes the handler on POST - Automatic JSON deserialization of request bodies
- Error handling with proper HTTP status codes
- Correct Content-Type headers
- Full Spin HTTP component integration
Important: Input Validation
Just like with the TypeScript SDK, tools should NOT validate inputs themselves. The FTL gateway handles all input validation against your tool's JSON Schema before invoking your handler. This means:
- Your handler can assume all inputs match the schema
- Focus on business logic, not validation
- The gateway enforces all JSON Schema constraints
Best Practices
-
Use serde for Input Types: Define input structs with
#[derive(Deserialize)]
-
Leverage ToolResponse Helpers: Use convenience methods like
ToolResponse::text()
andToolResponse::error()
-
Keep Metadata in Sync: Ensure your input schema matches your Rust struct definition
-
Error Handling: Return
ToolResponse::error()
for business logic errors - the macro handles panics
Example with Spin
The #[tool]
macro automatically generates the Spin HTTP component handler:
use tool;
use ToolResponse;
use Deserialize;
use JsonSchema;
/// Processes the input value
// That's it! The macro generates the HTTP handler for you.
// No need to write any additional code.
Async Support
The #[tool]
macro automatically detects whether your function is async and generates the appropriate code:
use tool;
use ToolResponse;
use Deserialize;
use JsonSchema;
use ;
/// Get weather for a location (async example)
async
Custom Schemas (Advanced)
While the macro automatically derives schemas from your types, you can still provide a custom schema if needed:
License
Apache-2.0