1.0.3 • Published 11 months ago

@guildadev/jsonapi-to-model v1.0.3

Weekly downloads
-
License
-
Repository
-
Last release
11 months ago

Introduction

The package leverages the best of metaprogramming, allowing direct access to data through an abstract model that represents a database table.

See .docs/motivation.md

Installation

yarn add @guidadev/jsonapi-to-model

or

npm install @guidadev/jsonapi-to-model

Performance

I created a benchmark to compare the performance of deserializing JSON:API data and directly accessing the included data. The results are as follows:

Benchmark TypeTotal ItemsDeserialization TimeTotal TimeGet Photos in IncludedPhotos IDsIncluded Length
Deserialize100070ms70ms0ms108771000
Model10000ms0ms1ms108771000

Why is the model faster? Because we don't need to parse the entire JSON:API payload. We only need to allocate the object, which is faster than parsing the entire JSON:API payload.

Usage

Here's how you can start using @guidadev/jsonapi-to-model in your projects:

// model/User.ts
import { Attribute, BaseEntity } from "@guildadev/jsonapi-to-model";

export class User extends BaseEntity {
  @Attribute()
  declare name: string;
}

// services/users.ts
export function useUsersQuery() {
  return useQuery<User[]>({
    queryKey: ["users"],
    queryFn: async () => {
      const request = await api.get('/user')
      const data = request.data
      const user = new User(data);

      return user;
    },
  });
}

export function useUserQuery() {
  return useQuery<User>({
    queryKey: ["user", 1],
    queryFn: async () => {
      const request = await api.get('/user/1')
      const data = request.data
      const user = new User(data);

      return user;
    },
  });
}



// Component.tsx
import { useUserQuery } from "@/provider/useUserQuery";

export default function Hello() {
    const { data: user, isLoading } = useUserQuery();
  
    if (isLoading) {
        return <div>Loading...</div>;
    }
    if (!user) {
        return <div>User not found</div>;
    }
  
    return <div>Hello, {user.name} </div>;
}

in tsconfig, inside compilerOptions, you need add:

{
  "experimentalDecorators": true,
  "useDefineForClassFields": true
}

Check how we are using in React, NextJS and Angular: https://github.com/GuildaDev/jsonapi-to-model-apps-demo

You can also get metas, array of JSON:API, object member metas

Check more on: model-object.test.ts and model-arrays.test.ts

Limitations

Even though esbuild and Vite 5 allow the use of experimentalDecorators (without reflection support), SWC does not support this feature. To work around this limitation in SWC, you can use internal helpers.

See limitations

References:

https://www.typescriptlang.org/docs/handbook/decorators.html

1.0.3

11 months ago

1.0.2

11 months ago

1.0.1

11 months ago

1.0.0

11 months ago