Skip to main content
@craft-ts
LearnLearn with EffectAI agentsGuideReference
@craft-ts/core@craft-ts/component@craft-ts/dev-tools@craft-ts/effect@craft-ts/style@craft-ts/style-testing@craft-ts/i18n@craft-ts/i18n-effect@craft-ts/mcp
ExamplesMigrationEffect compatibility & maturityAdopting CraftTS progressivelyPress kitRoadmapBacklog
Beta
  • Learn
  • Learn with Effect
  • AI agents
  • Guide
  • Reference
  • Packages
  • Resources
  • Guide overview
  • Create a project
i.Core concepts
  • The mental model
  • Which primitive should I use?
  • Anatomy of a primitive
  • Generators and yield*
  • Insertions
  • Typed insertion pipes
  • Exceptions as values
ii.Managing state
  • Local state
  • State machines
  • query
  • Mutations
  • queryParams
  • asyncProcess
  • Selecting
  • Reacting to mutations
  • Collections
  • Collection utilities
  • Persistence
  • GlobalPersisterHandler
  • Pagination placeholders
  • Schema validation
iii.Recommended approaches
  • Inject at the point of use
iv.Structuring the app
  • craftService
  • Service scopes
  • Shaping the public API
  • Abstract services
  • App start
  • Lazy services
  • Server functions
  • craftRegisterFor
  • Target wrapper
v.Routing & type-safe DI
  • Setup
  • CLI automation
  • ESLint rules
  • Route providers
  • Route guards
  • Route exception handling
  • Non-blocking navigation
  • Global error component
  • Route load errors
  • Scaling routes
vi.Components & templates
  • Components
  • Activating the style system
  • Typed styles
  • Defining a design system
  • Tokens and variables
  • Global foundation and fonts
  • Pseudo-elements and animations
  • Axes and the matrix
  • Context obligations
  • Testing visual states
  • Text contrast
  • Visual attestation
  • Template obligations
  • Typed CSS variables
  • Fine-grained reactivity
  • Progressive rendering
  • Directives and .pipe(...)
  • settledValue & pendingNode
  • Accessibility
  • Customization
  • Content projection
  • Styling a component
  • Template migrator
vii.Forms
  • Overview
  • Validators
  • Submitting
  • Nested forms
  • Exception handling
  • Complete examples
viii.Testing
  • Testing services
  • Testing components
  • Type-level tests
  • Browser boundaries
  • Page stability
  • Architecture rules
    • Overview
    • Declarative baseline
    • Unique identities
    • HTTP endpoint ownership
    • Computed purity
    • Dependency cycles
    • Mutation reactions
    • Route DI proofs
    • Route component files
    • Path boundaries
    • Exclusive links
    • Persisted identities
    • insertSelect keys
    • craftEffect and network
    • craftEffect and imperative sync
    • Interactive element names
    • Metric thresholds
    • Server-state loaders
    • Primitive loader requirements
  • Extensible architecture graph
  • Graph insights
  • Craft graph vs Nx
ix.Reactivity utilities
  • craftComputed
  • craftEffect
  • craftMethod
  • source$
  • on$
  • fromEventToSource$
  • sourceFromEvent
  • afterRecomputation
x.Internationalisation
  • Type-safe i18n
  • The catalogue
  • Tokens
  • The runtime
  • With Effect
xi.Deployment (experimental)
  • Overview
  • Manifest reference
  • Diagnostics
  • Providers
  • Alchemy provider
xii.Going further
  • SSR and hydration
  • Effect integration
  • Program operators
  • Pattern matching
  • Observability
  • AI agents
  • Temporal runtime
  1. Structuring the app
  2. Server functions

Public and protected server functions#

serverFunction is a transport contract. Authentication and authorization are middleware concerns: do not add an access: 'admin' option or a parallel protectedServerFunction helper.

The canonical path#

client middleware
  → handshake / client context
  → existing server middleware
  → verified session and role
  → server-function handler
  → Effect service and Layer

The browser may announce an identifier through clientContext, but that value is untrusted. The server must load the session again and compare the claim with the verified identity. A missing, expired or revoked session must stop the middleware chain before the handler runs.

Transport failures#

Every client-side server-function transport failure is returned as a typed HttpError, including a lost connection, an aborted request, an unavailable fetch implementation or an unreadable response. Network failures use status: 0 and statusText: 'Unknown Error', following the same convention as CraftHttpClient; the original failure is available in the error payload's body field.

This means callers can handle connection loss through the normal Craft exception path instead of adding a raw Promise rejection handler:

ts
const result = yield * getAnimals({});
if (isCraftException(result) && result._tag === 'HttpError') {
  // show a retry action or an offline state
}

The same normalization is applied to custom transports registered with provideServerFunctionTransport(...). Business failures returned by the server keep their own typed tags and are not converted to HttpError.

Public function#

ts
export const listPublicAnimals = serverFunction(
  'animals.public-list',
  inputSchema,
  { exposure: 'client', output: outputSchema },
).handler(({ input }) =>
  Effect.gen(function* () {
    const repository = yield* AnimalRepository;
    return yield* repository.list(input.filter);
  }),
);

Protected function#

Reuse the same middleware mechanism for the protected path:

ts
export const listAdminAnimals = serverFunction(
  'animals.admin-list',
  inputSchema,
  { exposure: 'client', output: outputSchema },
)
  .use(requireAdminSession)
  .handler(({ input }) =>
    Effect.gen(function* () {
      const repository = yield* AnimalRepository;
      return yield* repository.listForAdmin(input.filter);
    }),
  );

requireAdminSession is a craftMiddleware(...).server(...) value. It should return an explicit authentication/authorization failure when there is no valid session or the role is insufficient. The handler is then only responsible for the business operation.

For middleware shared by many functions, the optional createServerFunctionFactory([middleware]) factory applies those existing .use(...) calls in order; it does not introduce a new security policy API.

See the executable public/protected example in apps/demo-with-server-function, especially craftMiddleware, clientContext, craftHandshake and .use(...). Its server tests cover no session, a valid session and revocation. Keep the server test beside the function so the middleware wiring remains visible. The demo maps the two session failures to explicit 401 responses and maps a non-admin session to a 403 response.

Find the pieces#

  • serverFunction

  • craftMiddleware

  • clientContext

  • craftHandshake

  • Effect Layers and requirements

Useful search terms are auth, authentication, authorization, session, role, access policy and middleware.

←Lazy servicescraftRegisterFor→

On this page

  • The canonical path
  • Transport failures
  • Public function
  • Protected function
  • Find the pieces

@craft-ts · MIT licensed

GitHubnpm

Search