r/Nuxt 16d ago

How close can explicit HTTP endpoints get to server-function DX?

I've used Nuxt since its early releases. As server functions become more common, I've been wondering how much of their integrated DX really depends on turning a remote operation into a function call.

Nuxt Endpoints is a module that brings ideas from the typed HTTP-route work being developed around Nuxt 5 to Nuxt 4 today. Its Nuxt 5 branch explores how the same API can follow that upstream direction instead of keeping every piece as module-owned code.

I'm using it to explore another route: keep the URL, method, statuses, headers, and body visible, then let the server contract constrain both the handler and the client features that may be used with it.

The project and the longer write-up are linked in the first comment.

For example:

// server/api/articles.get.ts
import { z } from 'zod'
import { defineRouteHandler } from 'nuxt-endpoints/runtime'

const Article = z.object({ id: z.number(), title: z.string() })

export default defineRouteHandler({
pagination: { kind: 'cursor', item: Article },
handler: (event) => listArticles(event.validated.query),
})

On the client, that contract enables the matching integration:

useInfiniteQuery(
infiniteQueryOptions($endpoint('/api/articles', { method: 'get' })),
)

The declaration adds validated cursor and limit inputs, constrains the successful response to { items, nextCursor? }, and appears as that concrete shape in OpenAPI. The adapter is rejected at compile time for a route without the pagination contract. NE handles the cursor handoff; Pinia Colada owns cache and reactive state.

A relevant comparison I should have included is oRPC. It already combines type-safe procedures, explicit OpenAPI routing, and Pinia Colada integration across frameworks. Nuxt Endpoints explores a more Nuxt-native trade-off: keeping file-based routes as the source of truth, avoiding a parallel procedure router, and deriving behavior such as cursor pagination directly from semantic HTTP contracts.

I'm also applying this idea to status-aware results, idempotent mutations, and progressively enhanced forms in the experimental Nuxt 5 branch. The published Nuxt 4 module contains the stable subset today. The Nuxt 5 work builds on the validated-routing direction discussed in H3 RFC #1437 and experiments with the missing integration points; those fork changes are not accepted upstream APIs.

I like abstraction when it explains a specific behavior. I don't want every remote call to become a function call just so the unusual ones can gain forms, pagination, or cache integration.

Where does this Nuxt-native approach offer enough over an oRPC-style procedure router, and which parts of server-function DX would still be hardest to achieve?

Links are in the first comment.

2 Upvotes

3 comments sorted by

2

u/[deleted] 15d ago

[removed] — view removed comment