Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return the compiled schema with $ref resolved #336

Closed
ferronrsmith opened this issue Nov 4, 2016 · 6 comments
Closed

Return the compiled schema with $ref resolved #336

ferronrsmith opened this issue Nov 4, 2016 · 6 comments

Comments

@ferronrsmith
Copy link

Is there a way to get the schema with all the references resolved ?

@epoberezkin
Copy link
Member

The short answer is no (and there won't be, because in general case it is not possible).
It is explained in #22 and #125.

@epoberezkin
Copy link
Member

To repeat here the reasons why it is not possible:

  1. recursive $refs
  2. $ref is not equivalent to the object inclusion, because the $refs inside $ref should be resolved based on id in the source schema and not based on id of the current schema.

@RS-Roshi
Copy link

RS-Roshi commented Dec 5, 2018

I have found a possible way to get compiled schema with resolved references.. maybe it could help.

//Using Angular 7 Syntax
//parent schema-- must follow id#/JSON Pointer even to resolve reference from same file as below for "loc"
schema: any = {
    "$id": "schema.json",

      "type": "object",
      "properties": {
        "foo": { "$ref": "defs.json#/definitions/int" },
        "hel": { "$ref": "defs.json#/definitions/int" },
        "bee": { "$ref": "defs.json#/definitions/int" },
        "loc": { "$ref": "schema.json#/definitions/str" },
        "bar": { "$ref": "defs.json#/definitions/str" }
    },
    "required": ["foo"]
  };
  //child schema
  defsSchema: any = {
    "$id": "defs.json",
        "definitions": {
          "int": { "type": "integer", "title": "Hello" },
          "str": { "type": "string" }
        }
  };
  //ajv instance
  ajv: any = new Ajv({schemas: [this.schema, this.defsSchema]});
  //on intialize function because i want to console the output as the web intialize
  ngOnInit(){

    this.schema = this.ajv.getSchema('schema.json'); //output in validate function that has same schema
    this.dereferencedObj = this.dereference(this.schema.schema);//calling the dereference function and setting its returened value
    console.log(this.dereferencedObj);
   
  }
//function that will dereference the schema object and return you the compile schema object
   dereference(obj, id = null) {
    if(id == null) {
      id = obj.$id
    }
    //lodash function to separate keys and values of object
    _.forOwn(obj, (value, key, obj) => {
      if(value.$ref) {
        let schemaRef //store the $ref value 
        if(_.startsWith(value.$ref, '#')) {
          schemaRef = id + value.$ref.substr(1) //for reference in same schema
        } else {
          schemaRef = value.$ref // when reference is external

        }
        obj[key] = this.ajv.getSchema(schemaRef).schema //set the resolve value to the obj[key]
        
      }
      if(_.isObject(value)) {
        this.dereference(value, id)
      }
    })
    return obj //return compiled schema with resolved references.
  }

@kenisteward
Copy link

@RS-Roshi how reliable has this been for you? I'm looking into doing something like this but I want to make sure nothing needs added.

@RS-Roshi
Copy link

RS-Roshi commented Apr 9, 2019

@kenisteward above solution works great with referenced schemas but it doesn't work in case you have recursive references.
Getting compiled schema from recursive references is way more complicated so answering your question

"It works in Resolving References but for non-recursive schemas only".

@naz
Copy link

naz commented Sep 29, 2020

Another possible solution to resolving $ref in schema definitions is using separate library - ref-parser.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

5 participants