Skip to content
New issue

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

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

Already on GitHub? # to your account

The word "Items" appears in swagger-editor after resolving $ref using json-refs #105

Closed
sanjay-ng opened this issue Feb 7, 2017 · 24 comments

Comments

@sanjay-ng
Copy link

After using the json-refs resolve for $ref's the converted json is placed on swagger-editor and result show "items" which may not be appropriate per Swagger Specs.

Please clarify.

Sample Json:

"definitions": { "A1": { "title": "A1", "type": "object", "description": "", "properties": { "a2": { "type": "array", "items": { "title": "A2", "type": "object", "description": "", "properties": { "ids": { "type": "object", "properties": { "items": { "title": "IDS", "type": "object", "description": "", "properties": { "id": { "type": "string", "x-tag": 11, "description": "Specifies a mandatory id" }, "name": { "type": "string", "x-tag": 12, "description": "Specifies the name" }, "description": { "type": "string", "x-tag": 13, "description": "Specifies some description" } } } }, "x-tag": 11, "description": "some comments" } } }, "x-tag": 11, "description": "some comments" } } } }

image

@whitlockjc
Copy link
Owner

I'm not sure I fully understand the question.

@sanjay-ng
Copy link
Author

Ok, do you see the word "items" on the image attached right pane. I was wondering whether is it appropriate to display "items"?

I've json schema for swagger-editor and have many $ref's to resolve which in turn the swagger is not able to resolve using url so, I used your tool to convert to full definitions.

Another question, whether swagger-editor uses your nodejs module "json-refs" to resolve the $ref?

@whitlockjc
Copy link
Owner

swagger-editor uses sway which uses json-refs. As for your example screenshot, it looks like swagger-editor is displaying what it's given. What are you expecting to be different?

@sanjay-ng
Copy link
Author

Thank you for the quick reply!

When I refer a json schema on swagger-editor which is in another json file. it shows undefined (attached image below marked red), Can you please help resolve this issue?
Thank you again in advance.

Here's the example below:
"A1": {
"title": "A1",
"type": "object",
"description": "",
"properties": { "a2": {
"type": "array",
"items": {
"title": "A2",
"type": "object",
"description": "",
"properties": {
"$ref": "http://localhost/swagger-editor/Json/id.json#/definitions/ids"
} },
"x-tag": 11,
"description": "some comments"
} } }

id.json
descriptions: { "ids": {
"type": "object",
"properties": { "items": {
"title": "IDS",
"type": "object",
"description": "",
"properties": {
"id": {
"type": "string",
"x-tag": 11,
"description": "Specifies a mandatory id"
},
"name": {
"type": "string",
"x-tag": 12,
"description": "Specifies the name"
},
"description": {
"type": "string",
"x-tag": 13,
"description": "Specifies some description"
} } } } }}

image

@whitlockjc
Copy link
Owner

If you ever get undefined for a value, that means resolution succeeded but the value is itself undefined. In all other cases, json-refs will just leave the reference as-is and mark it as missing. One thing that looks wrong is that you have the URI http://localhost/swagger-editor/Json/id.json#/definitions/ids but it should be http://localhost/swagger-editor/Json/id.json#/descriptions/ids (notice descriptions vs. definitions).

See if that helps and I will try to see if I can reproduce the issue where a missing reference is given the value of undefined when it shouldn't be.

Note: I'm not sure if swagger-editor itself does anything above sway or json-refs so it could also be involved.

@sanjay-ng
Copy link
Author

sanjay-ng commented Feb 11, 2017

sorry my mistake, copy/paste error, it's "definitions" not "descriptions"

@whitlockjc
Copy link
Owner

Do you have a sample that can be ran via json-refs resolve SOME_FILE_OR_URL that reproduces this?

@sanjay-ng
Copy link
Author

Example, please paste it on the swagger-editor below code: (removed spaces for compact view)

{ "swagger": "2.0", "info": { "version": "1.0.0", "title": "Sites" }, "path": {}, "definitions": { "A1": { "title": "A1", "type": "object", "description": "", "properties": { "a2": { "type": "array", "items": { "title": "A2", "type": "object", "description": "", "properties": { "$ref": "http://localhost/swagger-editor/Json/id.json#/definitions/ids" } }, "x-tag": 11, "description": "some comments" } } } } }

Save the below json in file named "id.json" under folder named "json" (removed spaces for compact view)

{ "swagger": "2.0", "info": { "version": "1.0.0", "title": "id" }, "paths": { }, "definitions": { "ids": { "type": "object", "properties": { "items": { "title": "IDS", "type": "object", "description": "", "properties": { "id": { "type": "string", "x-tag": 11, "description": "Specifies a mandatory id" }, "name": { "type": "string", "x-tag": 12, "description": "Specifies the name" }, "description": { "type": "string", "x-tag": 13, "description": "Specifies some description" }, "config": { "type": "array", "items": { "$ref": "http://localhost/swagger-editor/Json/id.json#/definitions/properties/Config" }, "x-tag": 11, "description": "Specifies list of configured items in the System." } } } } }, "Config": { "title": "SomeConfig", "type": "object", "description": "", "properties": { "identifiers": { "type": "object", "properties": { "$ref": "http://localhost/swagger-editor/Json/id.json#/definitions/properties/Identifiers" }, "x-tag": 11, "description": "Specifies identifier" }, "algorithmName": { "type": "string", "x-tag": 13, "description": "Specifies algorithm names" }, "State": { "type": "boolean", "x-tag": 14, "description": "if set to true , indicates that is enabled" } } }, "Identifiers": { "title": "SomeIdentifiers", "type": "object", "description": "This will be used to identify", "properties": { "id": { "type": "string", "x-tag": 11, "description": "Specifies a mandatory identifier to uniquely represent" }, "name": { "type": "string", "x-tag": 12, "description": "Specifies the name" }, "description": { "type": "string", "x-tag": 13, "description": "Specifies some description" }, "state": { "type": "object", "properties": { "$ref": "http://localhost/swagger-editor/Json/id.json#/definitions/properties/AState" }, "x-tag": 31, "description": "Specifies the status" } } }, "AState": { "title": "AnalyticState", "type": "object", "description": "Specifies the states of Analytics", "properties": { "id": { "type": "string", "x-tag": 11, "description": "Specifies a mandatory identifier" } } } }

You'll notice that for a2(A2) it shows "undefined" on right pane of swagger-editior. The json has nested $ref's which also it must resolve. but it doesn't.

please let me know of any issues.

Thank you for your valuable time again!

@whitlockjc
Copy link
Owner

whitlockjc commented Feb 13, 2017

I'm not seeing this when using json-refs by itself. Here is the test I ran using json-refs resolve swagger.json:

{
  "swagger": "2.0",
  "info": {
    "version": "1.0.0",
    "title": "Sites"
  },
  "path": {},
  "definitions": {
    "A1": {
      "title": "A1",
      "type": "object",
      "description": "",
      "properties": {
        "a2": {
          "type": "array",
          "items": {
            "title": "A2",
            "type": "object",
            "description": "",
            "properties": {
              "type": "object",
              "properties": {
                "items": {
                  "title": "IDS",
                  "type": "object",
                  "description": "",
                  "properties": {
                    "id": {
                      "type": "string",
                      "x-tag": 11,
                      "description": "Specifies a mandatory id"
                    },
                    "name": {
                      "type": "string",
                      "x-tag": 12,
                      "description": "Specifies the name"
                    },
                    "description": {
                      "type": "string",
                      "x-tag": 13,
                      "description": "Specifies some description"
                    },
                    "config": {
                      "type": "array",
                      "items": {
                        "$ref": "id.json#/definitions/properties/Config"
                      },
                      "x-tag": 11,
                      "description": "Specifies list of configured items in the System."
                    }
                  }
                }
              }
            }
          },
          "x-tag": 11,
          "description": "some comments"
        }
      }
    }
  }
}

And here is a test I ran using sway:

{
  "swagger": "2.0",
  "info": {
    "version": "1.0.0",
    "title": "Sites"
  },
  "path": {},
  "definitions": {
    "A1": {
      "title": "A1",
      "type": "object",
      "description": "",
      "properties": {
        "a2": {
          "type": "array",
          "items": {
            "title": "A2",
            "type": "object",
            "description": "",
            "properties": {
              "type": "object",
              "properties": {
                "items": {
                  "title": "IDS",
                  "type": "object",
                  "description": "",
                  "properties": {
                    "id": {
                      "type": "string",
                      "x-tag": 11,
                      "description": "Specifies a mandatory id"
                    },
                    "name": {
                      "type": "string",
                      "x-tag": 12,
                      "description": "Specifies the name"
                    },
                    "description": {
                      "type": "string",
                      "x-tag": 13,
                      "description": "Specifies some description"
                    },
                    "config": {
                      "type": "array",
                      "items": {
                        "$ref": "id.json#/definitions/properties/Config"
                      },
                      "x-tag": 11,
                      "description": "Specifies list of configured items in the System."
                    }
                  }
                }
              }
            }
          },
          "x-tag": 11,
          "description": "some comments"
        }
      }
    }
  }
}

Here is the sway code:

var Sway = require('sway')

Sway.create({
  definition: 'swagger.json'
})
  .then(function (api) {
    console.log(JSON.stringify(api.definitionFullyResolved, null, 2))
  })
  .catch(function (err) {
    console.log(err.stack);
  })

So if json-refs and sway are not the culprit, I'm not sure what else I can do to help as it seems to be related to swagger-editor.

@sanjay-ng
Copy link
Author

sanjay-ng commented Feb 14, 2017

I agree with you that json-refs & sway are working fine when used independently, it's only with swagger-editor that it happens which in turn uses sway & json-refs module.

Besides, since sway & json-refs is able to resolve $ref I've a instance where the outputn of resolve has $ref which is nested again.... If sway/json-refs can identify if the output also has $ref and resolve it then it would be really nice may be some kind of option whether you want to resolve nested $refs, just a thought....

@whitlockjc
Copy link
Owner

If there are unresolved $ref entries in the resolved document, this means that resolving the error had errors but sway should tell you. Any chance your "http://localhost" URIs are not resolving properly and swagger-editor just isn't telling you?

@sanjay-ng
Copy link
Author

sanjay-ng commented Feb 15, 2017

correct, swagger-editor reports error:

message: "Reference could not be resolved:"
error: "Cannot use 'in' operator to search for 'definitions' in undefined"
level: 900
type: "Swagger Error"

@sanjay-ng
Copy link
Author

Did you get an chance to run the above json in swagger-editor?

@whitlockjc
Copy link
Owner

I've not. I will give it a shot and see if I can find out where the issue is. The error is somewhat suspect because I don't use the "in" JavaScript keyword so I'm betting that swagger-editor itself has a bug. I'll let you know.

@sanjay-ng
Copy link
Author

sanjay-ng commented Feb 15, 2017 via email

@whitlockjc
Copy link
Owner

I loaded the file you provided into http://editor.swagger.io/#/ and I see the error you're talking about. One thing that I can't fully explain is the error message. The error from json-refs/sway is Reference could not be resolved: http://localhost/swagger-editor/Json/id.json#/definitions/ids but then swagger-editor also mentions Cannot use 'in' operator to search for 'definitions' in undefined. Neither json-refs or sway uses the for in loop and that leads me to believe that swagger-editor is the one creating this error.

I'll keep looking.

@whitlockjc
Copy link
Owner

I think the error is in sway. After running it locally, it looks like the error is returned from sway so I need to figure out how to reproduce it so I can fix it. I will open the issue there and link this one.

@whitlockjc
Copy link
Owner

But just know, json-refs is working properly, it's just got a misleading error property for the error message.

@sanjay-ng
Copy link
Author

Thank you whitlockjc! I'll follow up and check on my side too.

@sanjay-ng
Copy link
Author

sanjay-ng commented Feb 20, 2017

And, suppose a json has nested $ref's then, does it resolves the nested ones too? While viewing in swagger-editor?

I'm debugging the sway & json-refs using swagger-editor on chrome will be able to pinpoint the code which is not getting the values for nested $ref probably in json-refs.....

@whitlockjc
Copy link
Owner

Yes, $ref are resolved recursively. There is a bug (#102) that is being fixed during the current rewrite but after that, it should be fully resolved.

@sanjay-ng
Copy link
Author

I may have fixed the nested $ref issue (which I mention in my earlier post) in json-refs but the problem now with my fix is it resolves all the nested $refs but cannot return resolved output to the resolveRefs() return object. Can you just help me out here? And, let me know if it works out.

I believe the calls might be repeated due to async....

The below I've placed just before the resolveRefs() ruturn line:

var refs = findRefs(obj, options); //checking if any $ref's
        if (Object.keys(refs).length > 0) { //if yes...
            Object.keys(refs).forEach(function (ref, i, arr) {
                resolveRefs(obj, options).then(function (result) { //resolve $refs
                    refs = findRefs(result, options); //find how many $refs left to resolve
                    //obj = result.resolved
                    if (Object.keys(refs).length === 0) //if nothing left to resolve then quit the loop
                        arr.length = 0;
                    else {
                        obj = result; //update the object fo next iteration
                        arr.length = result.ref;
                    }
                    return { //return these objects to outer return...
                        refs: result.refs, 
                        obj: result.resolved                        
                    };
                });                                   
            });            
        }

@sami7757
Copy link

sami7757 commented Mar 2, 2017

I believe you should call the resolveRefs again inside the success function of then,

`function processResult(result) { //resolve $refs
resultArray.push(result);
var refs = findRefs(result, options); //find how many $refs left to resolve
//obj = result.resolved
if (Object.keys(refs).length === 0) //if nothing left to resolve then quit the loop
arr.length = 0;
else {
processRefs(result.resolved, options).then(processResult);
obj = result; //update the object fo next iteration
arr.length = result.ref;
}
}
function processRefs(refs) {
if (Object.keys(refs).length > 0) { //if yes...
Object.keys(refs).forEach(function (ref, i, arr) {
resolveRefs(obj, options).then(processResult);
});
}
}

var refs = findRefs(obj, options); //checking if any $ref's
var resultArray= [];
processRefs(refs);`

@sanjay-ng
Copy link
Author

My earlier code was issuing warning on chaining, cleaned it but still the outer return doesn't give the inner return resolved refs object. here is the code...

var refs = findRefs(obj, options); //checking if any $ref's
        if (Object.keys(refs).length > 0) { //if yes...
            Object.keys(refs).forEach(function (ref, i, arr) {
                resolveRefs(obj, options).then(function (result) { //resolve $refs
                    refs = findRefs(result.resolved, options); //find how many $refs left to resolve
                    //obj = result.resolved
                    if (Object.keys(refs).length === 0) //if nothing left to resolve then quit the loop
                        arr.length = 0;
                    else {
                        obj = result.resolved; //update the object fo next iteration
                        arr.length = Object.keys(refs).length;
                    }
                    return { //return these objects to outer return...
                    refs: result.refs,
                    obj: result.resolved                   
                    };
                });                                   
            });            
        }

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

No branches or pull requests

3 participants