Route handlers

When builtin handlers cannot satisfy business need, custom route handlers come to the rescue. The custom route handler requires entity generation and programming.

Model route handler

Let's start with a custom model with a custom route handler.

entity rust {
    provider: .rust,
    dest: "./src/entities"
}
 
model User {
    @id @autoIncrement @readonly
    id: Int
 
    declare handler myHandler(CreateArgs<User>): Result<User>
}

Run entity generation:

cargo teo generate entity

Write logics for the handler:

app.main_namespace_mut().define_model_handler_group("User", |group| {
    group.define_handler("myHandler", |request: Request, teo: Teo, ctx: Ctx, create_args: UserCreateArgs| async move {
        let user = teo.user().new(create_args.create()).await?;
        Ok::<Response, Error>(Response::data(user.to_teon().await?))
    });
});

Custom route handler group

Some handlers may not belong to a model. In these cases, use a custom handler group instead.

entity rust {
    provider .rust
    dest "./src/entities"
}
 
model User {
    @id @autoIncrement @readonly
    id: Int
 
    declare handler myHandler(CreateArgs<User>): Result<User>
}
 
declare handler group MyHandlerGroup {
    declare handler myHandler(CreateArgs<User>): Result<User>
}

In the programming side, alter define_model_handler_group with define_handler_group.

app.main_namespace_mut().define_handler_group("MyHandler", |group| {
    group.define_handler("myHandler", |request: Request, teo: Teo, ctx: Ctx, create_args: UserCreateArgs| async move {
        let user = teo.user().new(create_args.create()).await?;
        Ok::<Response, Error>(Response::data(user.to_teon().await?))
    });
});

Custom HTTP method

Teo supports custom HTTP methods.

declare handler group MyHandlerGroup {
    @method(.get)
    declare handler myHandler(Any): Result<User>
}

Path parameters

Teo supports path parameters.

declare handler group MyHandlerGroup {
    @method(.get) @path("/my-route/:id", ignorePrefix: true)
    declare handler myHandler(Any): Result<User>
}

To retrieve path parameters, access it from the context.

app.main_namespace_mut().define_handler_group("MyHandlerGroup", |group| {
    group.define_handler("myHandler", |request: Request, teo: Teo, ctx: Ctx| async move {
        let captures = ctx.handler_match().captures();
        Ok::<Response, Error>(Response::data(Value::String(captures.get("id").unwrap().to_owned())))
    });
});

If a parameter contains /, use * instead of :.

declare handler group MyHandlerGroup {
    @method(.get) @path("/my-route/*path", ignorePrefix: true)
    declare handler myHandler(Any): Result<User>
}