Skip to main content

Crate apiplant_function

Crate apiplant_function 

Source
Expand description

§apiplant-function

Write an apiplant function without the ABI boilerplate.

Instead of hand-implementing the apiplant_abi traits, exporting a root module, and shuttling JSON in and out by hand, you write one ordinary typed function and call function!:

use apiplant_function::prelude::*;

#[derive(serde::Deserialize, Default)]
struct Config { #[serde(default)] greeting: String }

#[derive(serde::Deserialize, JsonSchema)]
struct Input { name: String }

#[derive(serde::Serialize, JsonSchema)]
struct Output { message: String }

fn greet(ctx: &Context<Config>, input: Input) -> Result<Output, String> {
    Ok(Output { message: format!("{}, {}!", ctx.config().greeting, input.name) })
}

apiplant_function::function! {
    name: "greet",
    description: "Greets a person",
    method: Post,
    visibility: Public,
    handler: greet,
}

The macro generates the root module, reads/writes JSON, resolves typed config and input, and turns your Err(_) into a 400. Types are inferred from the handler’s signature — you never name them twice. With the default schema feature the input and output types must also derive JsonSchema so the endpoint shows up typed in the OpenAPI docs.

Use functions! to export several from one library — each with its own name, manifest and handler.

§Functions as lifecycle hooks

A function can also be attached to a resource’s lifecycle from models/<name>.toml, in which case Context::hook carries the operation’s context — the row created or fetched, the rows a list returned, the request URL, the caller’s auth status — and the reply helpers say what should happen next. One function per event, so a handler never has to work out why it was called:

fn post_after_create(ctx: &Context<()>, row: serde_json::Value) -> Result<serde_json::Value, String> {
    let actor = ctx.hook().and_then(|hook| hook.principal_id.clone());
    ctx.info(&format!("post {} created by {actor:?}", row["id"]));
    Ok(reply::proceed())
}

apiplant_function::functions! {
    {
        name: "post_after_create",
        description: "Records a newly created post",
        method: Post,
        visibility: Private,
        handler: post_after_create,
    },
}

Modules§

prelude
A curated set of imports for function authors: use apiplant_function::prelude::*;.
reply
What a hook handler returns to the host.

Macros§

function
Define and export one apiplant function from a plain handler.
functions
Define and export several apiplant functions from one library.

Structs§

Context
The handle a function receives for one invocation.
Email
A message to send with Context::send_email.
Hook
Everything the host knows about the operation a hook fired for.
Sent
The receipt Context::send_email returns: which provider took the message, and what it called it.