Backend

RESTful API

Explain the fetcher mapping, supported scope, and json-server-style conventions in @ginjou/with-rest-api.

@ginjou/with-rest-api is a fetcher adapter for generic REST-style backends.

It follows json-server-style query conventions such as _start, _end, _sort, and _order.

This package only provides a fetcher adapter. It does not provide auth, authz, realtime, notification, or i18n contracts.

Installation

pnpm add @ginjou/with-rest-api

Scope

The adapter implements these fetcher methods today.

Fetcher methodStatusNotes
getListSupportedUses json-server-style pagination, sorter, and filter query keys.
getOneSupportedRequests {resource}/{id}.
createOneSupportedSends params as the request body.
updateOneSupportedSends params as the request body to {resource}/{id}.
deleteOneSupportedSends params as the request body when present.
customSupportedPowers both useCustom and useCustomMutation.
getManySupportedRequests {resource}?id=1&id=2 in one call.
createManyHandled by coreNot implemented here.
updateManyHandled by coreNot implemented here.
deleteManyHandled by coreNot implemented here.

json-server has no bulk endpoints, so the adapter does not implement the *Many mutations. useCreateMany, useUpdateMany, and useDeleteMany fall back to one createOne / updateOne / deleteOne request per record and return the responses in the same order as the input.

getMany is the one bulk read the backend can do in a single request. The backend decides the order of the returned records, and ids it does not know about are simply absent from the response, so data can be shorter than ids. Pass aggregate: false and read records by id if you need to match them up.

Fetcher

Use createFetcher() to build one Ginjou fetcher and register it through defineFetchersContext().

createFetcher() accepts these props.

PropRequiredMeaning
urlYesBase URL used by the resource methods.
clientNoCustom ofetch-compatible client. If omitted, the adapter creates its own client.

In Vue, register it at the app root.

import { defineFetchersContext } from '@ginjou/vue'
import { createFetcher } from '@ginjou/with-rest-api'

defineFetchersContext({
    default: createFetcher({
        url: 'https://api.example.com',
    }),
})

In Nuxt, pass $fetch when you want the adapter to use Nuxt's request client.

import { defineFetchersContext } from '@ginjou/vue'
import { createFetcher } from '@ginjou/with-rest-api'

export default () => defineFetchersContext({
    default: createFetcher({
        url: '/api',
        client: $fetch as any,
    }),
})

URLs

These are the request shapes produced by the adapter.

MethodDefault HTTP methodPathQueryBody
getListGET{url}/{resource}pagination + sorters + filtersnone
getOneGET{url}/{resource}/{id}nonenone
getManyGET{url}/{resource}id repeated once per idnone
createOnePOST{url}/{resource}noneparams
updateOnePUT{url}/{resource}/{id}noneparams
deleteOneDELETE{url}/{resource}/{id}noneoptional params
customnormalized from top-level methodurl as passed to the methodsorters + filters + querypayload is forwarded as request params

Resource methods use url as baseURL and build the final path from the resource name.

custom is different. It uses the provided url directly instead of combining it with the fetcher base URL.

custom also forwards payload as request params, not as the request body.

Pagination

Pagination is translated into _start and _end.

Ginjou inputREST query
currentUsed to calculate _start and _end
perPageUsed to calculate _start and _end

The adapter uses this formula:

Query keyValue
_start(current - 1) * perPage
_endcurrent * perPage

For totals, the adapter reads the x-total-count response header.

If that header is missing, it falls back to data.length.

Filters

Only a small set of operator mappings is implemented.

Ginjou filterREST query key
{ field: 'q', operator: 'eq', value }q=value
eqfield=value
nefield_ne=value
gtefield_gte=value
ltefield_lte=value
containsfield_like=value

Logical filters are not supported.

OperatorBehavior
orThrows an error
andThrows an error

Other operators do not currently get a dedicated suffix mapping in this adapter.

They fall back to a plain field=value query key.

Sorters

Sorters are translated into _sort and _order.

Multiple sorters are joined with commas.

Ginjou inputREST query
[{ field: 'name', order: 'asc' }]_sort=name, _order=asc
[{ field: 'name', order: 'asc' }, { field: 'age', order: 'desc' }]_sort=name,age, _order=asc,desc

Meta

For the standard resource methods, meta.method and meta.headers are forwarded into the outgoing request.

Meta fieldUsed by
meta.methodgetList, getOne, getMany, createOne, updateOne, deleteOne
meta.headersgetList, getOne, getMany, createOne, updateOne, deleteOne

For custom, use the top-level method and headers props instead.

The adapter normalizes custom methods like this:

Custom method inputHTTP method sent
get and unknown stringsGET
deleteDELETE
post, put, patchPUT

This is the literal current implementation, so post and patch are also sent as PUT.

import { useGetList } from '@ginjou/vue'

useGetList({
    resource: 'posts',
    meta: {
        method: 'POST',
        headers: {
            'X-Custom': 'value',
        },
    },
})
Copyright © 2026