Skip to content

Latest commit

 

History

History
239 lines (178 loc) · 8.48 KB

File metadata and controls

239 lines (178 loc) · 8.48 KB

Frontend Adapters (Vite / Next and others)

This guide is for frontend developers building user-facing surfaces against Platform BFF (admin, portal, public, embedded, and other product-mounted screens). You do not need to know Go module internals or storage layout. Admin examples below are the current proof set, not the architectural boundary.

Platform default is renderer-agnostic runtime: BFF contract + your renderer adapter. Vite/Next/React examples below are one adapter path, not the Platform default architecture.

Mental model

Think of /bff/* like server props or a loader in Next.js:

// App Router server component or loader
const screen = await fetch(`${API}/bff/screens/go-admin/posts`, {
  credentials: "include",
}).then((r) => r.json())

You receive a UI model, not raw posts[]. The backend already decided:

  • view type (table, form, kanban, dashboard, …);
  • columns and fields;
  • row actions and capabilities;
  • nav items for the current user;
  • metadata bridges to REST (list_api, form_action).

Data hydration vs UI hydration

Kind Owner Your responsibility
Data/model hydration BFF Rows, pagination, form values, validation, action metadata arrive in /bff/* JSON
UI hydration Your adapter React hydrate, islands, partial client boot, SSG enhancement

Do not expect BFF to perform React hydration or island boot. Fetch the model, then activate UI in your renderer.

Vite dev proxy

// vite.config.ts
export default {
  server: {
    proxy: {
      "/bff": "http://127.0.0.1:8080",
      "/go-json": "http://127.0.0.1:8080",
      "/go-login": "http://127.0.0.1:8080",
    },
  },
}

Use credentials: "include" so session cookies reach the app.

Core fetches

const screen = await bff.getScreen("go-admin/posts")
const nav = await bff.getNav()
const session = await bff.getSession()
Endpoint Returns
/bff/screens/go-admin/posts ScreenModel
/bff/nav { items: NavItem[] }
/bff/session { version, authenticated, principal_id, profile_id, capabilities }

Auth: 401 = not logged in; 403 = logged in but forbidden. Handle in UI, do not expect redirect HTML from JSON routes.

Renderer registry (not a fixed switch)

Platform provides base view types. Your app registers components:

const viewRegistry: Record<string, ComponentType<{ screen: ScreenModel }>> = {
  table: TableScreen,
  form: FormScreen,
  kanban: KanbanScreen,
  dashboard: DashboardScreen,
  // product-specific extensions:
  chat: ChatScreen,
  "telegram-bot": TelegramBotScreen,
}

export function AppScreen({ screen }: { screen: ScreenModel }) {
  const View = viewRegistry[screen.view] ?? UnsupportedScreen
  return <View screen={screen} />
}

You do not wait for Platform changes for every new product screen. Add a renderer component and have the product module return view: "chat" (or similar).

Base views (Platform primitives)

view Typical payload
table columns, rows, row_actions, pagination, metadata.list_api
form fields, form_record, metadata.form_action
kanban grouping metadata, cards (when hydrated)
dashboard sections[], optional widgets[], metric/status/chart/activity payloads

Use screen.fallback when your renderer lacks a specialized view (e.g. render kanban as grouped table).

When to call REST vs BFF

Task API
Render page/screen structure (any surface) /bff/screens/...
Mutate via declared actions (proof: admin forms) POST /bff/actions/... per metadata.form_action
Load/save records for integrations /go-json/... per metadata.list_api
Show who is logged in /bff/session
Build navigation chrome /bff/nav

Stage 6 ships POST /bff/actions/* for AppCMS post create/update/trash. Form screens expose metadata.form_action, metadata.action_scope, and metadata.action_token. React FormView submits BFF actions via fetch with FormData; Templ posts native HTML forms to the same paths.

Parity with reference renderer

Official proof screens must match Templ reference semantics:

  • AppCMS: /go-admin/posts
  • AppCRM: /go-admin/crm/leads

Same ScreenModel.id, view, resource, columns/fields, metadata, and nav. Styling may differ; behavior must not.

Deferred Frontend DX Contract (Pass 6)

React/Vite/shadcn DX is deferred until after Platform BFF freeze. Platform stabilizes the contract artifacts below; future frontend adapters build on them without changing Platform core.

Stable now (Platform freeze)

Artifact Path Use for future DX
JSON Schema schema/bff/v1/*.schema.json Validate /bff/* responses
TypeScript contract web/contract (@fastygo/bff-contract) Shared types and validators
Golden fixtures pkg/conformance/testdata/bff/v1/ Local fixture mode, tests, adapter dev
Conformance matrix pkg/conformance/bffparity/ Expected semantics per proof screen

Adapter authors can implement table/form screens from schema + fixtures today. No official React hooks or shadcn mapping are part of the frozen surface.

Future proof responsibilities (after Platform stabilization)

Deferred React/Vite/shadcn proof should later provide:

Capability Purpose
Generated or hand-authored TypeScript types Stay aligned with @fastygo/bff-contract / schema
Typed BFF client getScreen, getNav, getSession, action posts
useScreen Fetch and cache ScreenModel by path
useAction Submit POST /bff/actions/* with validation handling
useSession Auth and capability projection from /bff/session
useNavigation Capability-filtered nav from /bff/nav
shadcn component mapping Map BFF field/column types to UI primitives
Local fixture mode Render proof screens without a Go server
Vite proxy example Dev workflow against AppCMS/AppCRM :8080
Templ parity Same proof screens as Pass 5 minimum set

These are adapter-layer helpers, not Platform core APIs.

Do not implement during Platform freeze

  • official React package or full frontend SDK;
  • Next, Vue, or PHP/Handlebars adapter products beyond existing thin proofs;
  • create-fastygo-app or app generator;
  • shadcn component pack as a Platform requirement;
  • React-specific assumptions in pkg/bff, pkg/render, or Platform kernel.

web/react remains an optional compatibility proof, not stabilized Platform DX.

Stage 5 React/Vite proof (compatibility only)

Official compatibility proof lives at web/react in the Platform repo. It is a proof renderer, not stabilized Platform DX and not the default stack:

cd web/react
npm install
npm run dev

Proof routes (with AppCMS or AppCRM on :8080):

  • /cms/posts -> /bff/screens/go-admin/posts
  • /crm/leads -> /bff/screens/go-admin/crm/leads
  • /cms/posts/edit -> /bff/screens/go-admin/posts/post-rest/edit

Kit: src/fastygo (Screen, TableView, FormView, Nav, ActionButton). UI8Kit is not required for JSON BFF renderer adapters.

Stage 7 fixture parity (shipped)

JSON BFF adapters (React/Vite proof and third-party renderers) must consume the canonical fixtures under pkg/conformance/testdata/bff/v1, not ad-hoc local copies. The React proof imports fixtures through web/react/tests/fixtures.ts.

Adapter tests should validate:

  • validateScreenModel(fixture) passes;
  • view dispatch (table / form) matches fixture view;
  • metadata semantics (list_api, form_action, action_scope) render correctly;
  • volatile action_token is injected at runtime, not baked into fixtures.

Stage 8 renderer ecosystem (shipped)

Published artifacts for third-party adapters:

Artifact Path
JSON Schema schema/bff/v1/*.schema.json
TypeScript contract web/contract (@fastygo/bff-contract)
Thin adapter proofs examples/renderer-adapters

React imports the shared contract package instead of owning private BFF types. Standard table and form rendering needs no Go module changes — drop a new fixture JSON and validate against screen.schema.json.

Step-by-step adapter authoring: renderer-adapter-authoring.md.

Related documents