0.1.9 • Published 10 months ago

i-graphql v0.1.9

Weekly downloads
-
License
MIT
Repository
github
Last release
10 months ago

iGraphQL

ORM for dbs and GraphQL. The mission is to make graphql zeus typings database friendly. This is an alpha version and supports mongodb only.

Installation

npm i -D graphql-zeus
npm i i-graphql mongodb

Generation

$ npx zeus https://example.com/graphql ./src

Now when you generated your types you can use them inside project

Example

src/orm.ts

import { ModelTypes } from "./zeus";
import { iGraphQL } from "i-graphql";

export const orm = async () => {
  return iGraphQL<
    Pick<ModelTypes, "Operation" | "Invoice" | "Source">,
    {
      _id: () => string;
      createdAt: () => string;
      updatedAt: () => string;
    }
  >({
    Operation: '_id',
    Invoice: '_id',
    Source: '_id'
  },{
    autoFields:{
      _id: () => new ObjectId().toHexString(),
      createdAt: () => new Date().toISOString(),
      updatedAt: () => new Date().toISOString(),
    }
  });
};

export const MongOrb = await orm();

First we declared that we will use 3 types that are keys from ModelTypes type. Then We specified the type of autoFields generation functions that all of our models will use. Then our first function argument is a dictionary holding primary keys of our models, second parameter is options that hold autoFields generators that are used by the function createWithAutoFields

How to use your orm

const resolver = () =>
  MongOrb("Source").createWithAutoFields(
    "_id",
    "createdAt"
  )({
    name: "My Source",
  });

Experimental data loader

You can use experimental data loader for requests that can cause n+1 problem. It is still in experimental phase. Consider the following schema

type Person{
  id: String!
  username:String!
  friends: [Person!]!
}

type Query{
  person(_id:String!): Person!
}

And the following query:

query GetPersonWithFriends{
  person(id:"38u198rh89h"){
    username
    id
    friends{
      username
      id
      friends{
        username
        id
      }
    }
  }
}

Here is how you can implement to limit db calls and avoid n+1 problem

const peopleLoader = dataLoader<{[id:string]: PersonModel}>({})

export const QueryPeople = async (_,args) => {
  const person = await MongoOrb("Person").collection.findOne({_id:args._id})
  const friends = await MongoOrb("Person").collection.find({
    _id:{
      $in: person.friends
    }
  }).toArray()
  const friendsOfFriends = await MongoOrb("Person").collection.find({
    _id:{
      $in: friends.flatMap(f => f.friends)
    }
  })
  const allPeople = Object.fromEntries([person,...friends,friendsOfFriends].map(p => ([p.id,p])))
  return peopleLoader.withData(person,allPeople) 
}

export const PersonFriends = (src,args) =>{
  const source = peopleLoader.fromSrc(src)
  return {
    ...src,
    friends: src.friends.map(f => source.__dataLoader[f])
  }
}
0.1.8

11 months ago

0.1.7

11 months ago

0.1.9

10 months ago

0.1.4

11 months ago

0.1.6

11 months ago

0.1.5

11 months ago

0.1.3

1 year ago

0.1.2

2 years ago

0.1.0

2 years ago

0.1.1

2 years ago

0.0.9

2 years ago

0.0.8

3 years ago

0.0.7

3 years ago

0.0.5

3 years ago

0.0.6

3 years ago

0.0.4

3 years ago

0.0.3

3 years ago

0.0.2

3 years ago

0.0.1

3 years ago