vazco / uniforms

A React library for building forms from any schema.
https://uniforms.tools
MIT License
1.95k stars 240 forks source link

JSON Schema #112

Closed radekmie closed 7 years ago

radekmie commented 8 years ago

JSON Schema is a very good candidate for the next built-in schema. Writing a whole new validator is not the best idea, but using already existing one like ajv or is-my-json-valid is a good option as those seem to be quite popular and mature.

Thoughts? Ideas? Demands?

radekmie commented 8 years ago

@MacRusher @macrozone @serkandurusoy @zeroasterisk

macrozone commented 7 years ago

never used anything but simple-schema, because i also use collection2 to validate on inserts and updates, but for non-meteor-projects this might be interesting.

serkandurusoy commented 7 years ago

I would say the next evolution could somehow be related to graphql/apollo.

Frankly, I have never used uniforms outside of meteor either. Now I know uniforms offers much more and is in no way strictly coupled with simple schema, but I've always considered uniforms just because it indeed works well with simple schema and I have not considered it for non-meteor projects, you know just because much more widely accepted alternatives exist.

But I would say, if uniforms were to somehow offer similar value with graphql-based projects, it would prove to be even more beneficial.

On Mon, Oct 24, 2016 at 6:07 PM, Marco Wettstein notifications@github.com wrote:

never used anything but simple-schema, because i also use collection2 to validate on inserts and updates, but for non-meteor-projects this might be interesting.

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

radekmie commented 7 years ago

OK. As I can see, JSON schemas are not so popular (at least here), so I'll close it and open separate issue for graphql-related ideas.

mkrn commented 7 years ago

JSON schema is great and is becoming a standard. I would like to implement a JSON schema wrapper for uniforms.

At first I thought to convert JSON schema to Simpleschema and there is a convertor but won't be easy to use without meteor.

Let me know if someone have done this so far, otherwise i'd be happy to share once done if successful.

radekmie commented 7 years ago

@mkrn I don't think it would be a good idea, to mess it with SimpleSchema. If you want, I'd love to help you with it.

mkrn commented 7 years ago

@radekmie I'm starting at it right now.. trying to follow the MyLittleSchema example and documentation...

Some questions:

this.schema[name.replace(/\.\d+/g, '.$')] = what does this supoosed to mean? is it a way to reach to nested fields? what format the name would be in?

getSubfields - should it return properties for object and items for array?

getProps - not sure where's the list of props that it could return.. Is title one of those - to be used in label? Just need to know the possible names.

Thanks for reaching out! Let me know how to best collaborate I could start repository - should it just export the Bridge extended class?

radekmie commented 7 years ago

At first, I'd suggest creating a PR with a new JSONSchemaBridgeor JSONBridge directly in the uniforms package, just like the others. It's already on the roadmap to split them into packages.

About that regex: functions like getField will receive full field name, like friends.0.name - it's replacing all nested numbers (array indices) with $, to treat them as item of this array.

About getSubfields: only nested object properties. It should be [] for arrays.

About getProps: well, you can return anything. Also, label and placeholder have a little different meaning, you can trace it here.

radekmie commented 7 years ago

@mkrn?

oluckyman commented 7 years ago

I’m gonna make JSONSchemaBridge too. More detailed Bridge API documentation will help dramatically. What I’m missing is detailed description for each method, something like this:

/*
 * Field's scoped error.
 *
 * @param {string} name Is it the name of the field with error?
 * @param {object} error ... ?
 * @returns {object} Is there specific format it should return?
 */
getError (name, error) { /* ... */ }

...
oluckyman commented 7 years ago

Another question about validator. I’m gonna use ajv in my project, and seems I have to make a wrapper function validator which will be called this way validator(model).

import Ajv from 'ajv';
import mySchema from 'mySchema.json'; // some JSONSchema

const validator = (model) => {
  // use ajv and `mySchema` to validate `model`
  // throw errors if any
};

And then use it like this:

const schema = new JSONSchemaBridge(mySchema, validator);

render () {
  return <AutoForm schema={schema} />
}

I’m wondering should JSONSchemaBridge tightly depend on ajv validator or is it possible to make a bridge validator-agnostic?

radekmie commented 7 years ago

getError(name, error) should extract error object for the field called name (possibly nested, like a.b). What is this error object? It's either the error prop from your form or (only in ValidatedForm and derivatives), the error returned from the validator, obtained from getValidator. getValidator(options) should return a function of type model -> error.

For example: GraphQLBridge is completely validator-agnostic. Why? Because I've made a standard error format for it. In short, it looks like this: {details: [{name: 'a', message: 'A is required.'}, {name: 'c.d', message: 'Object C has a required field D.'}]}. Here is an example of usage.

oluckyman commented 7 years ago

Thanks @radekmie! could you please provide similar explanations for all other methods in the Bridge:

    getErrorMessage (/* name, error */) {
    getErrorMessages (/* error */) {
    getField (/* name */) {
    getInitialValue (/* name, props */) {
    getProps (/* name, props */) {
    getSubfields (/* name */) {
    getType (/* name */) {
    getValidator (/* options */) {

What’s type of input parameters. With examples of arguments. What’s expected as return value. With examples of return values. Where the method is used.

I would like to organise that info into comments for Bridge.js and make a PR for you to review

radekmie commented 7 years ago

Sounds good to me, @oluckyman!

class ExampleBridge {
    // Extract error object for the field called `name` from `error`.
    getError (name : string, error : BridgeError) : ?any {
        return error && error[name];
    }

    // Extract error message for the field called `name` from `error`.
    // If there's no error, return ''.
    getErrorMessage (name : string, error : BridgeError) : string {
        return error && error[name] && error[name].message || '';
    }

    // Extract all error messages from `error`.
    getErrorMessages (error : BridgeError) : string[] {
        return Object.keys(error).map(field => error[field].message);
    }

    // Schema-specific object passed as `field` prop.
    getField (name : string) : object {
        return {};
    }

    // Initial value of field called `name` with props `props`.
    getInitialValue (name : string, props : object) : ?any {
        return undefined;
    }

    // Additional props passed to the field called `name` with props `props`.
    // Props `label` and `placeholder` are somehow special, because of it's
    // inheritance style.
    getProps (name : string, props : object) : ?object {
        return {label: name};
    }

    // Names of subfields of field called `name`.
    // Example: for object {a: {b: 0, c: '', d: [1, 2, 3], e: {f: 0}}}
    //     getSubfields('a')   // ['b', 'c', 'd', 'e']
    //     getSubfields('a.b') // []
    //     getSubfields('a.c') // []
    //     getSubfields('a.d') // []
    //     getSubfields('a.e') // ['f']
    getSubfields (name : string) : string[] {
        return [/*...*/];
    }

    // Type of field called `name`, used for field component detection in the
    // <AutoField />. It's also passed as `fieldType` prop to the field.
    getType (name : string) : function {
        return String; // Or something.
    }

    // Validator used by <ValidatedForm /> and it's subclasses. These `options`
    // are passed through the `validator` prop of the form.
    getValidator (options : ?any) : (model : BridgeError) {
        // Here `validateWithOptions` is your function.
        return model => validateWithOptions(model, options);
    }
}

If you need more info or examples - let me know.

oluckyman commented 7 years ago

Currently I’ve switched to another project and put that task on hold. But I’m sure these comments will help anyone who works on their own Bridge implementation. @radekmie thanks a lot!

waheed25 commented 7 years ago

i just want to know uniforms supported json schema or not???

radekmie commented 7 years ago

No, it's not at the moment.

zeroasterisk commented 7 years ago

❤️