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

Relative $ref pointer not working for files #35

Closed
varver2 opened this issue Feb 27, 2017 · 11 comments
Closed

Relative $ref pointer not working for files #35

varver2 opened this issue Feb 27, 2017 · 11 comments

Comments

@varver2
Copy link

varver2 commented Feb 27, 2017

I have a nodejs application and a folder where all schema reside .
The folder are different for both as given below :

Node js application run here
-- /home/ubuntu/work/node_webhook/webhook.js

Json schema files are stored here :

-- /home/ubuntu/work/analytics/data_types/
------- mobile_schema
------------- test_schema.json
------------- test_2_schema.json
-------- enums.json
-------- common_data_types.json

test_schema.json looks like this :

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "amount": {
      "type": "integer"
    },
    "created_at_date": {
      "$ref": "../common_data_types.json#/common_types/date_time"
    },
    "current_stage": {
       "$ref": "../enum_server.json#/all_enum/CURRENT_STAGE"
    }
  },
  "required": [
    "amount",
    "created_at_date",
    "current_stage"
  ]
}

common_data_types.json looks like this :

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "common_types": {
    "date_time": {
      "type": "string",
      "format": "date-time"
    }
  }
}

enums.json looks like this

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "all_enum": {
    "PAYMENT_METHOD": {
      "type": "string",
      "enum": [
        "ONLINE",
        "OFFLINE"
      ]
    },
    "CURRENT_STAGE": {
      "type": "string",
      "enum": [
        "ONE",
        "TWO",
        "THREE"
      ]
    }
  }
}

AND NODE JS APLICATION FILE : webhook.js looks like this :

var express = require('express');
var app = express(); 
var $RefParser = require('json-schema-ref-parser');
var Validator = require('jsonschema').Validator;

var v = new Validator();
var parser = new $RefParser();

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var router = express.Router();              // get an instance of the express Router


// middleware to use for all requests
router.use(function(req, res, next) {
    console.log('Got a request.');
    next(); // make sure we go to the next routes and don't stop here
});


function validateEventSchema(req,res){
//console.log(req.body); 
var event_data = req.body.properties;
var parser = new $RefParser();
var event_schema = parser.bundle("/home/travel/work/trips3m/lib/analytics/data_types/mobile_schema/test_schema.json");

parser.dereference(event_schema, function(err, schema) {
  console.log(parser.$refs.paths())
  valid = false;
  if (err) {
    console.error(err);
  }
  else {
    //console.log(schema.properties.ts.type);
    c = v.validate(event_data, schema);
    if(c.errors.length > 0 ){
      console.log("ERROR OCCUR");
    }else{
      valid = true ; 
    }
  }

  console.log(valid)
}

router.route('/dump_thy_data')
  .post(function(req, res) {
      validateEventSchema(req,res)
  });

app.use('/', router);
app.listen(process.env.APP_PORT);

Getting error as it try to resolve ref pointers in current directory in which nodejs application is running . That is : /home/ubuntu/work/node_webhook/
So it cannot find
/home/ubuntu/work/node_webhook/enums.json
/home/ubuntu/work/node_webhook/common_data_types.json

How will i provide it a base directory to load all json files from . Or how to use relative file path ?

@varver2
Copy link
Author

varver2 commented Feb 27, 2017

@BigstickCarpet can you please help with this . Is there any way i can achieve what i am trying to do ?

@JamesMessinger
Copy link
Member

JamesMessinger commented Feb 27, 2017

There are a few errors in your code, which I think are the cause of the problem:

  • There's no need to call parser.bundle() and parser.dereference(). Just call one or the other.

  • You're calling parser.bundle() as though it's a synchronous method, which it's not. It's asynchronous, so you'll need to either provide a callback or accept a Promise.

@sul4bh
Copy link

sul4bh commented Apr 28, 2017

@BigstickCarpet
I have run into similar issue regarding "$ref" that points to a file location.

My question is, what is the base path for a relative path in $ref? Is the base path relative to where the json file is or is it relative to process.cwd()?

The code that I have right now behaves as if process.cwd() is the base path. Is it the right behavior? Does the spec say anything about it?

@JamesMessinger
Copy link
Member

@sul4bh - References are resolved relative to the containing file, per the spec.

@sorohan
Copy link

sorohan commented Jun 30, 2017

@BigstickCarpet I too had a similar issue with relative refs. I've created a commit here that reproduces the issue:
sorohan@28f12ff

The strangest thing is, if you remove the 'title' property from here, the test will pass:
https://github.com/sorohan/json-schema-ref-parser/blob/28f12ffdfed25f50f9889423d39487d1b683c713/test/specs/relative/relative.yaml#L4

@JamesMessinger
Copy link
Member

JamesMessinger commented Jun 30, 2017

@sorohan - Because your JSON Reference ($ref object) has an extra property (title), JSON Schema $Ref Parser will transparently create a new object that merges the properties of the resolved object and the $ref object. So, in your example, you end up with an object that looks like this:

{ 
  title: 'Test',
  type: 'object', 
  properties: { 
    id: { 
      type: 'string' 
    } 
  } 
}

@sorohan
Copy link

sorohan commented Jun 30, 2017

@BigstickCarpet. I think according to the schema additional properties should be ignored: http://json-schema.org/latest/json-schema-core.html#rfc.section.8

"All other properties in a "$ref" object MUST be ignored."

In any case, it seems to be breaking the file resolution. If you run with the test I added (npm run mocha) you should see an error:

Error: Error resolving $ref pointer "...json-schema-ref-parser/test/specs/two/id.json".
"...json-schema-ref-parser/test/specs/two/id.json" not found.

And removing the 'title' property stops the error.

@JamesMessinger
Copy link
Member

Yeah, I'm aware that merging extra properties of the $ref object violates the spec. But multiple people specifically requested that behavior, and my justification for adding it is that if you don't want the merging behavior, then you can avoid it by simply not adding extra properties to your $ref objects. Effectively it's opt-in behavior.

That said, the existence of extra properties shouldn't affect path resolution at all. I'll have to investigate when I get a chance. I have several tests for this functionality, and they all pass, so I'm not sure what's different about your example.

@gowthaman-murugan
Copy link

gowthaman-murugan commented Nov 15, 2018

I am facing the same issue. Please, someone, give me a solution for this

{ "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "properties": { "$ref": "../common_data_types.json#/common_types", "amount": { "type": "integer" }, "current_stage": { "$ref": "../enums.json#/all_enum/CURRENT_STAGE" } }, "required": [ "amount", "created_at_date", "current_stage" ] }

error
{ "name": "Error", "message": "Error resolving $ref pointer \"/home/ubuntu/gowthaman/json-schema/enums.json#/all_enum/CURRENT_STAGE\". \"/home/ubuntu/gowthaman/json-schema/enums.json\" not found.", "stack": "Error: Error resolving $ref pointer \"/home/ubuntu/gowthaman/json-schema/enums.json#/all_enum/CURRENT_STAGE\". \"/home/ubuntu/gowthaman/json-schema/enums.json\" not found. at $Refs._resolve (/home/ubuntu/gowthaman/json-schema/node_modules/json-schema-ref-parser/lib/refs.js:152:11) at dereference$Ref (/home/ubuntu/gowthaman/json-schema/node_modules/json-schema-ref-parser/lib/dereference.js:99:23) at /home/ubuntu/gowthaman/json-schema/node_modules/json-schema-ref-parser/lib/dereference.js:58:26 at Array.forEach (<anonymous>) at crawl (/home/ubuntu/gowthaman/json-schema/node_modules/json-schema-ref-parser/lib/dereference.js:51:24) at dereference$Ref (/home/ubuntu/gowthaman/json-schema/node_modules/json-schema-ref-parser/lib/dereference.js:112:24) at /home/ubuntu/gowthaman/json-schema/node_modules/json-schema-ref-parser/lib/dereference.js:58:26 at Array.forEach (<anonymous>) at crawl (/home/ubuntu/gowthaman/json-schema/node_modules/json-schema-ref-parser/lib/dereference.js:51:24)" }

@sorohan
Copy link

sorohan commented Nov 15, 2018

@gowthaman-i2i you can't merge together properties like that (mixing the $ref and the "amount", etc).

You might want to read about combining schemas:
https://json-schema.org/understanding-json-schema/reference/combining.html

@gowthaman-murugan
Copy link

@sorohan Thank you got it.

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

No branches or pull requests

5 participants