@void-snippets/client

ResourceService

Generic CRUD class — list, get, create, update, delete.

#ResourceService — Generic CRUD base class

Extend it once per API resource, pass the URL prefix in the constructor, and get five typed methods for free.

#Class signature

typescript
class ResourceService<
  TId,                                               // the resource's ID type, e.g. Contact.Id
  TBase,                                             // shape in list responses, e.g. Contact.Base
  TDetail    = TBase,                                // shape in single responses, e.g. Contact.Detail
  TCreate    = Partial<TBase>,                       // create payload
  TUpdate    = Partial<TBase>,                       // update payload
  TListRaw   = VSDefaultPaginatedResponse<TBase>,    // raw list response before adapter
  TSingleRaw = VSDefaultSingleResponse<TDetail>      // raw single response before adapter
>

#Built-in methods

MethodHTTPURL
list(params?)GET/endpoint?page=1&limit=10&…
get(id)GET/endpoint/:id
create(payload)POST/endpoint
update(id, payload)PATCH/endpoint/:id
delete(id)DELETE/endpoint/:id

All five methods automatically call handleApiError on failure, so you always receive a clean Error with a readable message.

#Step 1 — Define your types

typescript
// contacts/contacts.types.ts
import type { VSId } from '@void-snippets/core';

export namespace Contact {
  export type Id = VSId<string, 'Contact'>;

  // Shape in list responses (lean — just what a table row needs)
  export interface Base {
    _id:   Id;
    name:  string;
    email: string;
    phone: string;
  }

  // Shape in single-item responses (richer — full detail page)
  export interface Detail extends Base {
    createdBy: { _id: string; name: string };
    notes:     string;
    createdAt: string;
    updatedAt: string;
  }

  export namespace Apis {
    export interface Create {
      name:  string;
      email: string;
      phone: string;
    }
    export interface Update {
      name?:  string;
      email?: string;
      phone?: string;
      notes?: string;
    }
  }
}

#Step 2 — Create the service

typescript
// contacts/contacts.api.ts
import { ResourceService } from '@void-snippets/client';
import type { Contact } from './contacts.types';

export class ContactsApiService extends ResourceService<
  Contact.Id,         // TId
  Contact.Base,       // TBase   — returned by list()
  Contact.Detail,     // TDetail — returned by get(), create(), update(), delete()
  Contact.Apis.Create,
  Contact.Apis.Update
> {
  constructor() {
    super('/contacts'); // base path — list: GET /contacts, single: GET /contacts/:id
  }
}

export const ContactsApis = new ContactsApiService();

You can now call ContactsApis.list({ page: 1 }), ContactsApis.get(id), etc., anywhere in your app with full type safety.