Actions

Render functions control the data that is pushed from the server to the client. Anything that is sent from a client to a server is considered an action. Actions are internally implemented as POST requests that are handled in Javascript, but once built on the frontend should be fully transparent to you.


Passthrough

FUNCTIONmountaineer.actions.passthrough_dec.passthrough

passthrough

Only functions that are explicitly marked as actions will be accessable by the frontend. The @passthrough decorator indicates that this function should be called by the frontend and will return an explicit data payload. It will NOT update the render() state of the frontend.

Decorate functions within your ControllerBase that you want to expose. Each of these functions should specify a return type. Normal passthrough endpoints can return with either a None, a BaseModel object, or a JSONResponse if you need full flexibility on return headers and content structure.

If you do return a JSONResponse note that we will handle the merging of the response for you - so on the client side you will still access your endpoint contents as response.passthrough.

Parameters

  • Name
    args
    Type
    Description

    Default: ()

  • Name
    kwargs
    Type
    Description

    Default: {}

  • Name
    exception_models
    Type
    list[Type[APIException]] | None
    Description

    List of APIException subclasses that this function is known to throw. These will be parsed and available to frontend clients.

  • Name
    raw_response
    Type
    bool
    Description

    If specified, you can return a generic fastapi.Response object. There's no constraint this endpoint returns JSON - you can return html or a custom protocol. This lets you treat this API as a generic POST endpoint for you to fully control the output.

Code

const response = await serverState.my_action({ name: "John Appleseed", }); console.log(response.passthrough.name);

Code

from pydantic import BaseModel class ResponseModel(BaseModel): name: str class MyController(ControllerBase): @passthrough async def my_action(self, name: str) -> ResponseModel: return ResponseModel(name=name)

Sideeffect

FUNCTIONmountaineer.actions.sideeffect_dec.sideeffect

sideeffect

Mark a function as causing a sideeffect to the data. This will force a reload of the full (or partial) server state and sync these changes down to the client page.

Like passthroughs, @sideeffect accepts return values of None, BaseModel, or a JSONResponse if you need full flexibility on return headers and content structure. Unlike @passthrough, it does not allow you to provide a non-JSON response since we need to internally merge it with render() sideeffect update.

Parameters

  • Name
    args
    Type
    Description

    Default: ()

  • Name
    kwargs
    Type
    Description

    Default: {}

  • Name
    exception_models
    Type
    list[Type[APIException]] | None
    Description

    List of APIException subclasses that this function is known to throw. These will be parsed and available to frontend clients.

  • Name
    reload
    Type
    tuple[FieldClassDefinition, ...] | None
    Description

    If provided, will ONLY reload these fields on the client side. By default will reload all fields. Otherwise, why specify a sideeffect at all? Note that even if this is provided, we will still regenerate a fully full state on the server as if render() is called again. This parameter only controls the data that is streamed back to the client in order to help reduce bandwidth of data that won't be changed.

  • Name
    experimental_render_reload
    Type
    bool
    Description

    Experimental options. Disabled by default. If True, will attempt to only execute the logic in render() that is required to calculate your reload parameters. Other logic will be short-circuited. If your render function has significant computation for other properties this can be a significant performance improvement. However, it is experimental and may not work in all cases.

Code

from mountaineer import sideeffect, RenderBase, ControllerBase, Depends from iceaxe import DBConnection, select from iceaxe.mountaineer import DatabaseDependencies from myapp import models class ControllerRender(RenderBase): count: str class MyController(ControllerBase): async def render( self, db_connection: DBConnection = Depends(DatabaseDependencies.get_db_connection), ) -> ControllerRender: elements = await db_connection.exec(select(models.MyModel.id)) return ControllerRender(count=len(elements)) @sideeffect async def increment_count( self, db_connection: DBConnection = Depends(DatabaseDependencies.get_db_connection), ) -> None: new_model = models.MyModel() await db_connection.insert([new_model])