Procedures
Procedures allow you to add additional context to a set of server actions, such as the userId
of the caller. They are useful for ensuring certain actions can only be called if specific conditions are met, like the user being logged in or having certain permissions.
Creating a basic procedure
Here is an example of a simple procedure that ensures a user is logged in, and passes that information to the ctx of the handler
In this example:
- We create a
authedProcedure
that verifies the user is logged in by callinggetUser()
. - If successful, it returns the user's email and id. If not, it throws an error.
- We create an
updateEmail
by chainingcreateServerAction()
off the procedure. Invoking this action will now call the procedure's handler before running its own handler, thus ensuring that only authed users can use this server action.
Chaining procedures
What if you need to restrict an action based on additional conditions, like the user being an admin? You can create an chained procedure that to run a procedure AFTER another procedure and feed forward that ctx
.
In this example:
- We call
createServerActionProcedure
and chain off ofauthedProcedure
by passing it as an argument. - We use the
ctx
from theauthedProcedure
's handler and further determine if the user is an admin. - We create a
deleteUser
action that runs the two procedures, in order before the actions handler and also has access to theisAdminProcedure
's return value in thectx
. The action will now only run it's handler if the user is an admin and the inital procedure's don't throw an error.
Procedures with input
You can also create procedures that require certain input, such as requiring a postId
, and validate that the user has access to that resource:
Actions using this ownsPostProcedure
will now always require a postId
in the input
. It will now validate the user's ownership before executing the action's handler:
Now, when we call the updatePostName
, both postId
and newPostName
will be required in the input.
Chaining procedures is a powerful way to pass context into your actions and ensure that certain conditions are met before running the action's handler.