npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

airent

v0.1.10

Published

Airent Framework for JavaScript Backend - a lightweight data entity and presentation framework

Downloads

53

Readme

airent-js

Airent Framework - data entity management and presentation for JavaScript backend

Why Airent?

Avoid Backend Boilerplate

One pain point in backend development is to write boilerplate code for wiring up the data entities and fields. These boilerplate code exists in all of your database layer, your business logic, and your API presentation layer today.

Airent is designed to help you reduce the boilerplate code and focus on the business logic. Once you define your entity schema in YAML with Airent, it will automatically generate all the data entity classes and corresponding presentational types for you in TypeScript. You can then use these generated classes to load data from your database, compute fields, and present the data in your API endpoints. No more boilerplate code to write!

Eliminate N+1 Queries

When you load data from your database, you may encounter the N+1 query problem, where you load a list of entities and then need to load additional data for each entity in the list. This can lead to a large number of queries being executed, which can be slow and inefficient.

Airent provides a way to define the data loading strategy for each field in your entity schema. You can specify whether a field should be loaded directly from the database, computed from other fields, or loaded by foreign keys. Airent will then automatically generate the data loading logic for you, ensuring that you load the data in the most efficient way possible.

Reduce Error Prone Code

With most plain ORMs today, what you get is usually POJOs (Plain Old Java Objects), and in your downstream code you have to remember and manage the presence of specific fields which could lead to bugs and errors (like null or undefined fields).

Airent's intelligent framework will greatly improve your development experience and your backend service performance by automatically loading the necessary data and computing the fields for you only when they are used in the logic. You can then access the fields with confidence, knowing that they are always there and up-to-date.

Unify Data Computation

A lot of times, you may want to compute some fields based on the existing data in your database and reuse the logic in your business logic layer and API fields. For example, you may want to compute the age of a user based on their birthdate and reuse this logic all over the place.

Airent provides a simple way to define these computed fields in your schema, and empowers you to create customized data computation logic for both business logic layer and API presentation. These tailored fields are automatically loaded and computed according to the logic you define, all in a unified manner. You'll never have to worry about data computation again!

Streamline Data Presentation

When you expose your data through API endpoints, you may want to present only the necessary fields to the client to reduce the payload size and protect sensitive data.

Now, you can streamline data presentation on your API endpoints with Airent. Simply specify the desired fields you want to select, and let Airent handle the rest. No more worries about inadvertently exposing sensitive data!

Getting Started

Installation

First, install with npm:

npm install airent

Then, run the airent command to create the configuration file.

npx airent

You may specify "type": "module" if you are using ES modules. You should see the airent.config.js file in the root directory of your project:

{
  "type": "commonjs",
  "schemaPath": "schemas",
  "entityPath": "src/entities"
}

Build your data application with Airent

Define your entity schema

Create a new YAML file in your schema directory, e.g. schemas/user.yml:

name: User
# internal: true # set internal to true if you do not want to generate API response for this entity
model: PrismaUser
types:
  - name: PrismaUser
    aliasOf: User
    import: "@prisma/client"
fields:
  - id: 1
    name: id
    type: string
    strategy: primitive # this field is loaded from db directly
  - id: 2
    name: createdAt
    type: Date
    strategy: primitive
  - id: 3
    name: updatedAt
    type: Date
    strategy: primitive
  - id: 4
    name: email
    type: string
    strategy: primitive
  - id: 5
    name: firstName
    type: string | null
    strategy: primitive
  - id: 6
    name: lastName
    type: string | null
    strategy: primitive
  - id: 7
    name: imageUrl
    type: string | null
    strategy: primitive
  - id: 8
    name: isAdmin
    type: boolean
    strategy: computed # this field is computed from primitive fields without extra data loading
    internal: true # this field will not be exposed to the API response
  - id: 9
    name: chatUsers
    type: ChatUser[] # the ChatUser entity is defined in the types section above
    strategy: association # this field is to be loaded from db by foreign keys
    sourceKeys:
      - id # the key field in User entity
    targetKeys:
      - userId # the key field in ChatUser entity
    internal: true
  - id: 10
    name: messages
    type: Message[] # the Messsage entity is defined in the types section above
    strategy: association # this field is to be loaded from db by foreign keys
    sourceKeys:
      - id # the key field in User entity
    targetKeys:
      - userId # the key field in Message entity
    internal: true
  - id: 11
    name: firstMessage
    type: Message | null
    strategy: computedAsync # custom async load for this field

Generate your data entity classes and types

Run the airent code generation command:

npx airent

and then you will find the following generated code in your src/entities directory:

src
└── entities
    ├── generated           -> generated code, don't touch
    │   ├── message-base.ts -> base class for Message entity
    │   ├── message-type.ts -> type definition for Message field request and response
    │   ├── user-base.ts    -> base class for User entity
    │   └── user-type.ts    -> type definition for User field request and response
    ├── message.ts          -> Message entity class
    └── user.ts             -> User entity class

Use your data entity classes

Load your data with ORM, and create the entity instances:

import { PrismaClient } from "@prisma/client";
import { UserEntity } from "./entities/user";

const prisma = new PrismaClient();

const user = await prisma.user.findUnique({ where: { id: 1 } });
const userEntity = UserEntity.fromOne(user);

console.log(userEntity.id); // 1

const users = await prisma.user.findMany({ where: { id: { lt: 100 } } });
const userEntities = UserEntity.fromArray(users);

console.log(userEntities[0].id); // 1

Use the entity instance to access the data:

console.log(userEntity.email);
console.log(userEntity.isAdmin());
console.log(userEntity.await getLastMessage());

And present your entity in API endpoints:

import { PrismaClient } from '@prisma/client';
import { UserEntity } from './entities/user';

const prisma = new PrismaClient();

const user = await prisma.user.findUnique({ where: { id: 123 } });
const userEntity = UserEntity.fromOne(user);
const response = await userEntity.present({ id: true, firstMessage: true });

const users = await prisma.user.findMany({ where: { id: lt: 100 } });
const userEntities = UserEntity.fromArray(users);
const responses = await UserEntity.presentMany(userEntities);

This is it. Have fun!

Latest Updates

I've also developed a bunch of Airent Extensions. Check them out and enjoy the full power of Airent!

  • https://github.com/cshaxu/airent-prisma-js: Airent Extension for Prisma ORM, which automatically takes your Prisma schema DBML file and generate Airent schema YAML definitions. It also generates the data loaders for your entities so you don't need to write any data-level code at all!

  • https://github.com/cshaxu/airent-api-js: Airent API Extension, which provides an opinioned framework to write your entire backend with Airent. It automatically generates the backend-side services, actions and endpoint handlers for your entities, and provides a bunch of useful features such as authentication, authorization, and pagination. What's even more amazing is it also generates the frontend side SDK for your Airent APIs with field selection to help you build your frontend with ease!

  • https://github.com/cshaxu/airent-api-next-js: Airent API Extension for Next.js, which automatically generates the code for API routes for your Next.js project with app routing.

  • https://github.com/cshaxu/airent-api-express-js: Airent API Extension for Express.js, which automatically generates the code for API routes for your Express.js project.