Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

13 Commits

Repository files navigation

DEPRECATION NOTE:

This project has started a couple of years ago as we intended to create a way to allow developers to focus on building a structured domain based on well defined patterns instead of having the mess of loose uncoupled resolvers.

Unfortunately we haven’t had the proper time to develop this project further, so it has never gained enough momentum. Since then, as well, lots has changed in the ecosystem. A lot of the goals of this project have already been achieved by other projects, such as https://prisma.io.

Prisma is probably the way to go if you look for something mature and reliable. If you feel adventurous, though, you can take a look at our new experiment: https://github.com/zvictor/faugra.


the GraphObject Build Status

Don't let your graph oriented project become a mess. Add structure to it!

Disclaimer

This is an experimental project not ready for production use yet. Part of the features described in this document are still being implemented. The best way to check the features currently implemented is checking out our example app.

We are looking for feedback and are open for discussing the strategy adopted here. Do not hesitate opening an issue and sharing your thoughts with us, it will make us happy. :)

Install

npm install graph-object --save

Models Usage

new MyModel({ field: value })

import{Model}from'graph-object';classAuthorextendsModel{getname(){return`${this.firstName}${this.lastName}`;}}
>constorwell=newAuthor({firstName: 'George',lastName: 'Orwell'});>orwell.firstName'George'>orwell.name'George Orwell'

Authorization

Allow/Deny Access

allow(object, objectCRUD, fields_RU_)

import{allow,controlAccess}from'graph-object';classPostextendsModel{
...
}classAuthorextendsModel{getposts(){returnPost.objects.find({'author._id': this._id});}getpublicPosts(){returncontrolAccess(Post.objects.find({'author._id': this._id}))}allowedPosts(context){returncontrolAccess(Post.objects.find({'author._id': this._id}),context)}}allow(Post,{read(context){// Post's CRUD permissions could be changedreturnthis.author._id===context.userId||!this.private;},},{views: {// `view` field permissions.// Only `read` and `update` are available for fields.read(context){returnthis.author._id===context.userId;},update(context){returnfalse;}}});
>// someAuthor only published a private ({private: 1}) post.>someAuthor.posts
Error: 'read'permissionnotgrantedbyPost>someAuthor.public[]>someAuthor.allowedPosts({userId: 1})[Post]

Managers Usage

Managers are inspired in the Django's manager concept. More docs to come.

Connectors Setup

In order to retrieve and persist the data from your objects you should connect your models to your prefered storage provider. Graph-object is agnostic about that, so you can use any database and storage engines, as many as you want, as long as there are adapters available for them.

Note: If no connector is specified for a given class, it will by default use a dumb memory store.

The example below will give your managers access to both mongodb and memory stores.

importmodelsfrom'./models';importadapterfrom'graph-object-adapter-waterline';importmemoryAdapterfrom'sails-memory';importmongoAdapterfrom'sails-mongo';import{injectConnectors}from'graph-object';constpersistingModels=injectConnectors(models,adapter({default: {adapter: mongoAdapter,host: 'localhost',// defaults to `localhost` if omittedport: 27017,// defaults to 27017 if omitteduser: 'username_here',// or omit if not relevantpassword: 'password_here',// or omit if not relevantdatabase: 'database_name_here'// or omit if not relevantidentifiers: {Author: 'authors',Posts: 'posts',}},memory: {adapter: memoryAdapter,identifiers: {Author: 'people',Posts: 'posts',}},});exportdefaultpersistingModels;

Models, Managers and Connectors. What da heck!?!

If these concepts make you confused, this issue could help clarifying it.

GraphQL resolvers

Graph-object models are plug & play to GraphQL servers. Just make sure you run generateResolvers(schema, models) to have the resolvers generated.

importschemafrom'/domain/schemas';importpersistingModelsfrom'./models';import{apolloExpress}from'apollo-server';constresolvers=generateResolvers(schema,persistingModels);addResolveFunctionsToSchema(schema,resolvers);
...
app.use('/graphql',bodyParser.json(),apolloExpress({
schema,
resolvers,context: {},}));

Example

Please check out the Perfect GraphQL Starter for a working example app.

Motivate

If you like this project just give it a star :)

About

An Object Graph Mapper for GraphQL

Resources

Stars

8 stars

Watchers

4 watching

Forks

Releases

Packages

Used by

Contributors

Languages