Skip to content

Consider support $ref in jsonschema #76

@comfuture

Description

@comfuture

Thanks for the great tool json-schema-form!
it is very helpful because it is headless and can be used in any framework.

In many json schemas generated by other tools (e.g. OpenAPI, Pydantic, ...), you may see the keyword $ref which is used to reference another schema. This is a very useful feature to avoid duplication and keep the schema DRY.

It would be great if json-schema-form can support this feature. I have tried to use it but it seems not working. I have also checked the documentation and the source code but I cannot find any information about this.

Most of cases, the $defs is defined in the same definition, so it should be easy to implement.

ex) #/$defs/Person will point to the definition of {"$defs": { "Person": {... } } } in the same file.

So, before parsing the schema, we can resolve the $ref and replace it with the actual definition.
I've wrote some simple pseudo code to demonstrate how it can be implemented. I hope this will be helpful.

function getRef(path: string, object: any): any {
  const keys = path.replace(/^#/, '').split('/');

  let current = object;
  for (const key of keys) {
    if (key in current) {
      current = current[key];
    } else {
      return null;
    }
  }

  return current;
}

function resolveRefs(object: any, rootObject: any = object): any {
  for (const key in object) {
    const value = object[key];
    if (typeof value === 'object' && value !== null) {
      if ('$ref' in value) {
        const resolved = getRef(value['$ref'], rootObject);
        if (resolved) {
          object[key] = resolved;
        } else {
          // throw new Error('Cannot resolve reference: ' + value['$ref']);
          console.error('Cannot resolve reference:', value['$ref']);
        }
      } else {
        // go recursive
        resolveRefs(value, rootObject);
      }
    }
  }
  return object;
}

Then, add option to the createHeadlessForm function to enable this feature.

const { fields, handleValidation } = createHeadlessForm(schema, {
  resolveRefs: true, // or the referable other schema
})

I hope this feature will be implemented in the future. Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions