Uniforms: GraphQL integration

Created on 25 Oct 2016  Â·  8Comments  Â·  Source: vazco/uniforms

Note: Created as a successor of this comment in #112.

More and more projects are using graphql, so some kind of integration would be nice. Some research about parsing graphql schemas would be nice _(and I'll probably do it in some free time)_, but further customizations directly in schema might be an overkill.

Ideas? Thoughts?

enhancement

Most helpful comment

Good news!

GraphQL support just landed in 1.6.0-beta.1! Go and try it! Bugs reports are welcome!

All 8 comments

@MacRusher @macrozone @serkandurusoy @zeroasterisk

OK, I have some very basic implementation here. We have few problems to solve, in order to make it real:

  1. How to handle custom scalars?
  2. How to handle IDs?
  3. How to validate plain objects? _(some kind of (object + schema) -> mutation + mutation validator)_
  4. How to pass initial values?
  5. How to pass additional props?

https://github.com/kuip/meteor-schema-graphql-bridge could spark some ideas
perhaps

sorry I'm on my phone but I'm really excited about this and will post more
soon!

Sent from my iPhone

On Oct 25, 2016, at 21:48, "RadosÅ‚aw Miernik" [email protected]
wrote:

@MacRusher https://github.com/MacRusher @macrozone
https://github.com/macrozone @serkandurusoy
https://github.com/serkandurusoy @zeroasterisk
https://github.com/zeroasterisk

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/vazco/uniforms/issues/118#issuecomment-256136967, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AEbz3HEmkOSM4LUsilUNnmok021_dzRqks5q3k8XgaJpZM4KgV6Q
.

There's also graphql-forms. As I looked into the source, they simply ignore custom scalars.

Here are my conclusions:

  1. GraphQLBridge can't really validate a model because it have no other knowledge than the type of the field and it _requireness_.
  2. Because 1., you'll have to create GraphQLBridge instance by hand.
  3. Because 1., you'll have to implement your own validation _(you should do it anyway, yes?)_.
  4. Using QuickForm _(and other self-generated forms)_ is making almost no sense because there's no way to provide additional field props in the schema _(we _could_: keep reading)_.
  5. If you want to have a form with custom scalar type, then you can't rely on AutoField, because it won't guess your field type.

Example:

const schema = new GraphQLBridge(`
    type Author {
        # Label
        id:        ID!
        decimal:   Float
        firstName: Int
        lastName:  String
        posts:     [Post]
    }

    type Post {
        id:     Int!
        title:  String
        author: Author
        votes:  Int
    }

    # This will be used as the form schema.
    type Query {
        posts: [Post]
    }
`, model => {
    if (!model.posts || model.posts.length === 0) {
        // This is just example.
        // Structure inspired by ValidationError.
        throw {
            details: [
                {field: 'posts', message: 'At least one post is required.'}
            ]
        };
    }

    // More validation...
});

Looks good, huh? Now, let's take a look at additional props. We can pass it to the schema, as a third parameter:

const schema = new GraphQLBridge(graphQL, validator, {
    posts: {
        minCount: 1,
        maxCount: 4
    },

    // Again - it's just an example.
    // Notation inspired by SimpleSchema.
    'posts.$.title': {
        placeholder: 'Some creative title...'
    }
});

What do you think? If you think, this will work _(and it's enough)_, then we have it! My _experimental_ bridge is almost it!

But wait, there's more!

If you don't like the idea of passing _raw_ schema to the GraphQLBridge, we can also do it like this:

import {makeExecutableSchema} from 'graphql-tools';

const executableSchema = makeExecutableSchema({...});

// Any type can be passed to the form.
const schema = new GraphQLBridge(executableSchema.getType('Post'), ...);

Wow, indeed I like the new GraphQLBridge() approach. It looks like a good
balance between flexibility and structure. That being said, perhaps we can
actually look into abstracting the third parameter a little bit such that
perhaps it can accept multiple "schema formats" thus aligning it with your
original vision, right?

On Wed, Nov 2, 2016 at 9:23 PM, RadosÅ‚aw Miernik [email protected]
wrote:

Here are my conclusions:

  1. GraphQLBridge can't really validate a model because it have no
    other knowledge than the type of the field and it _requireness_.
  2. Because 1., you'll have to create GraphQLBridge instance by hand.
  3. Because 1., you'll have to implement your own validation _(you
    should do it anyway, yes?)_.
  4. Using QuickForm _(and other self-generated forms)_ is making almost
    no sense because there's no way to provide additional field props in the
    schema _(we could: keep reading)_.
  5. If you want to have a form with custom scalar type, then you can't
    rely on AutoField, because it won't guess your field type.

Example:

const schema = new GraphQLBridge(type Author { # Label id: ID! decimal: Float firstName: Int lastName: String posts: [Post] } type Post { id: Int! title: String author: Author votes: Int } # This will be used as the form schema. type Query { posts: [Post] }, model => {
if (!model.posts || model.posts.length === 0) {
// This is just example.
// Structure inspired by ValidationError.
throw {
details: [
{field: 'posts', message: 'At least one post is required.'}
]
};
}

// More validation...

});

Looks good, huh? Now, let's take a look at additional props. We can pass
it to the schema, as a third parameter:

const schema = new GraphQLBridge(graphQL, validator, {
posts: {
minCount: 1,
maxCount: 4
},

// Again - it's just an example.
// Notation inspired by SimpleSchema.
'posts.$.title': {
    placeholder: 'Some creative title...'
}

});

What do you think? If you think, this will work _(and it's enough)_, then
we have it! My _experimental_ bridge
https://gist.github.com/radekmie/9c228b5ad55fec927efb768eb0d697e7 is
almost it!
But wait, there's more!

If you don't like the idea of passing _raw_ schema to the GraphQLBridge,
we can also do it like this:

import {makeExecutableSchema} from 'graphql-tools';
const executableSchema = makeExecutableSchema({...});
// Any type can be passed to the form.const schema = new GraphQLBridge(executableSchema.getType('Post'), ...);

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/vazco/uniforms/issues/118#issuecomment-257955267, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AEbz3JIICFM-P0puHEtS3pkoGeFeBikkks5q6NUpgaJpZM4KgV6Q
.

Every form is already abstracted from the schema. This logic is placed in createSchemaBridge(schema). The only limitation here is that form have a schema prop - we can't pass multiple parameters in there. I think, that creating the bridge by hand is the best and the cleanest solution.

Good news!

GraphQL support just landed in 1.6.0-beta.1! Go and try it! Bugs reports are welcome!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tab00 picture tab00  Â·  8Comments

cyclops24 picture cyclops24  Â·  6Comments

rafahoro picture rafahoro  Â·  3Comments

simplecommerce picture simplecommerce  Â·  4Comments

thearabbit picture thearabbit  Â·  6Comments