Skip to content

Introduction

Most data-access layers are tied to a protocol (a REST client, a GraphQL client) or to a framework. nexdk separates two things:

  • the call grammar (resource.method), the same for every backend;
  • the driver, which translates that grammar to one protocol.

A multi-backend app (catalogue over GraphQL, orders over REST, presence in realtime) is written with one API. Resources are validated by any Standard Schema validator (Zod, Valibot, ArkType).

nexdk is not published to npm yet. Clone the repository, then:

Terminal window
pnpm install
pnpm build

Once published, install the SDK, the driver and what the driver needs. REST drivers need @nexdk/http, the supabase driver needs @supabase/supabase-js:

Terminal window
pnpm add nexdk @nexdk/http @nexdk/driver-nest
pnpm add nexdk @supabase/supabase-js @nexdk/driver-supabase
import { createSdk, defineResource } from 'nexdk'
import { createNestDriver } from '@nexdk/driver-nest'
import { z } from 'zod'
const product = defineResource({
name: 'products',
schema: z.object({ id: z.number(), name: z.string() }),
})
export const sdk = createSdk({
drivers: { nest: createNestDriver({ baseUrl: 'https://api.example.com' }) },
resources: { nest: { products: product } },
})
const { data: products, error } = await sdk.nest.products.get({ page: 1 })

A call resolves { data, error } and does not throw. Check error first: data is then typed from the schema. createSdk({ ..., throw: true }) returns the bare value and rejects instead.

From here: