Skip to content
DomainKit
Esc
navigateopen⌘Jpreview
On this page

Server API

Mount provider connection routes in Effect-native or async hosts while retaining application ownership of identity, persistence, and policy.

domainkit/server supplies one provider-connection HTTP seam for Effect-native and async hosts. Identity, tenancy, credentials, short-lived continuations, durable authorization storage, and audit policy remain host-owned.

Async hosts

Use createDomainKit in a conventional async application. It accepts Promise-based host capabilities and returns a standard Web handler:

import { createDomainKit } from "domainkit/server";

export const domainKit = await createDomainKit({
  baseURL: "https://app.example.com",
  basePath: "/api/domainkit",
  defaultReturnTo: "/domains",
  identity: hostIdentity,
  connectionPolicy: hostConnectionPolicy,
  providers: [cloudflare],
  pendingAuthorizations: redisPendingAuthorizations,
  persistence: managedDnsConnections,
});

The host supplies persistence; DomainKit does not choose a database, run migrations, or dispose the host’s database client. The optional @domainkit/capsuledb package remains an Effect-native implementation rather than an implicit dependency of this factory.

Effect-native hosts

Use Server.make in an existing Effect program or provide it as a Layer with Server.layer:

import { Server } from "domainkit/server";
import { Layer } from "effect";

const dependencies = Layer.mergeAll(
  IdentityLive,
  ConnectionPolicyLive,
  ProvidersLive,
  PendingAuthorizationsLive,
  ManagedDnsConnectionsLive,
  CryptoLive,
);

const DomainKitServerLive = Server.layer({
  baseURL: "https://app.example.com",
  basePath: "/api/domainkit",
  defaultReturnTo: "/domains",
}).pipe(Layer.provide(dependencies));

export const domainKit = Server.toWebHandler(DomainKitServerLive);

Both paths use the same route program. Server.make leaves Effect requirements visible; createDomainKit adapts Promise capabilities at the foreign-runtime boundary.

Mount the handler

The returned fetch(Request) works directly with Web-standard server frameworks.

app.all("/api/domainkit/*", (context) => domainKit.fetch(context.req.raw));
// app/api/domainkit/[...path]/route.ts
export const GET = domainKit.fetch;
export const POST = domainKit.fetch;
// routes/api/domainkit/$.ts
export const Route = createFileRoute("/api/domainkit/$")({
  server: {
    handlers: {
      GET: ({ request }) => domainKit.fetch(request),
      POST: ({ request }) => domainKit.fetch(request),
    },
  },
});

Dispose the DomainKit handler during a long-lived host’s shutdown. This releases only the runtime created by DomainKit; the host still owns its persistence lifecycle. The default base path is /api/domainkit. When baseURL is omitted, the start request’s origin constructs the callback URL; configure it explicitly behind a reverse proxy or custom domain.

Routes

Method Path Behavior
POST /api/domainkit/connection/start Authenticates the host principal and returns an authorization URL
GET /api/domainkit/callback/:providerId Consumes state once, commits the connection, and redirects

The start body accepts providerId, method, an optional provider-selection domain, an optional existing authorizationId, and a same-origin returnTo. When authorizationId is present, Server.ConnectionPolicy must authorize that exact aggregate for the authenticated principal before DomainKit can reuse it. Callback redirects append domainkit=connected and the public connectionId so the host UI can continue its setup flow.

Host services

Export Purpose
Server Routes, configuration, host service tags, errors, and the Web handler adapter
Service Host responsibility
Server.Identity Authenticate a start request and return tenant-owned principal identifiers
Server.ConnectionPolicy Authorize an exact existing aggregate before connection reuse
Server.Providers Build a configured interactive provider flow for the selected domain and callback
Server.PendingAuthorizations Persist the opaque continuation and safe callback context until one-time consume
ManagedDnsConnections.Service Persist the durable authorization, credential, connection, and attachment aggregate
Crypto.Crypto Generate continuation, authorization, and connection identifiers

createDomainKit is also a named export for Promise hosts. Its identity, connectionPolicy, providers, pendingAuthorizations, and persistence options correspond to these Effect services. Build Effect sibling implementations with Layer.mergeAll, then provide the completed dependency graph to Server.layer once.

Failure behavior

Failures are returned as JSON with category, message, operation, and retry. Start requests without a host identity return 401, and denied aggregate reuse returns 403. Invalid provider input, unsafe return URLs, mismatched callbacks, expired state, and replayed state return 400. Configuration failures return 500, provider infrastructure failures return 502, and storage failures return 503. Provider tokens and opaque continuation payloads are never serialized to the browser response.

Was this page helpful?