i-graphql
TypeScript icon, indicating that this package has built-in type declarations

0.1.9 • Public • Published

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])
  }
}

Readme

Keywords

none

Package Sidebar

Install

npm i i-graphql

Weekly Downloads

24

Version

0.1.9

License

MIT

Unpacked Size

43.5 kB

Total Files

17

Last publish

Collaborators

  • slothking