@bjornharrtell/json-api
    Preparing search index...

    @bjornharrtell/json-api

    json-api

    NPM Version Coverage Status

    json-api can fetch typed data models via a JSON:API endpoint into normalised records and/or post or update them.

    An instance is created with an endpoint and model definitions and the instance API provides methods findAll, findRecord to fetch record(s). Included relationships will be automatically resolved. If relationships for a record are not included they can be fetched later using findRelated. A record can be created or updated saveRecord.

    Additionally support for the atomic operation extension exists via types and saveAtomic.

    A service returning the canonical example JSON:API document at https://jsonapi.org/ can be consumed this way:

    import { useJsonApi, type BaseEntity, type ModelDefinition, RelationshipType } from '@bjornharrtell/json-api'

    export interface Person extends BaseEntity {
    firstName?: string
    lastName?: string
    twitter?: string
    }

    export interface Comment extends BaseEntity {
    body?: string
    author?: Person
    }

    export interface Article extends BaseEntity {
    title?: string
    author?: Person
    comments?: Comment[]
    }

    const modelDefinitions: ModelDefinition[] = [
    {
    type: 'people',
    },
    {
    type: 'comments',
    relationships: {
    author: { type: 'people', relationshipType: RelationshipType.BelongsTo },
    },
    },
    {
    type: 'articles',
    relationships: {
    author: { type: 'people', relationshipType: RelationshipType.BelongsTo },
    comments: { type: 'comments', relationshipType: RelationshipType.HasMany },
    },
    },
    ]

    export const articlesApi = useJsonApi({
    endpoint: 'http://localhost/api',
    modelDefinitions,
    })

    The above can then be used as follows:

    import { articlesApi, type Article } from './api/articles'

    const { records: articles } = await articlesApi.findAll<Article>('articles', {
    include: ['comments', 'author']
    })
    expect(articles.length).toBe(1)
    const article = articles[0]
    expect(article.id).toBe('1')
    expect(article.title).toBe('JSON:API paints my bikeshed!')
    expect(article.comments?.length).toBe(2)
    expect(article.comments?.[0]?.body).toBe('First!')
    expect(article.comments?.[1]?.body).toBe('I like XML better')
    expect(article.author?.firstName).toBe('Dan')