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

Allow schema $refs to not have to start with #/definitions #954

Conversation

domharrington
Copy link
Contributor

@domharrington domharrington commented Jun 14, 2018

Reasons for making this change

We're using this module to render forms for Swagger/OAS files. $refs
in swagger are stored in components/schemas at the top level of the object.

This change allows $ref strings to not always start with #/definitions/
which is a much easier solution than us having to recursively modify $refs
to prefix with this value.

All existing tests are passing, with a new test for this functionality.

The change was to make the definitions part of the regular expression an
optional non-capturing group.

Edit: any reason why you dont commit the package-lock.json file?

Edit 2: also, is there any main reason (apart from keeping the repo clean) why you don't commit the built source files (in lib/ and dist/?) This makes it tricky to npm install from a fork, as lib/index.js doesn't exist in git.

Checklist

  • I'm adding or updating code
    • I've added and/or updated tests
    • I've updated docs if needed
    • I've run npm run cs-format on my branch to conform my code to prettier coding style

Dom Harrington added 2 commits June 13, 2018 17:10
This allows you to simply run `mocha test-file.js` without having to remember to add all the extra stuff
We're using this module to render forms for Swagger/OAS files. $refs
in swagger are stored in `components/schemas` at the top level of the object.

This change allows $ref strings to not always start with `#/definitions/`
which is a much easier solution than us having to recursively modify $refs
to prefix with this value.

All existing tests are passing, with a new test for this functionality.

The change was to make the definitions part of the regular expression an
optional non-capturing group.
domharrington pushed a commit to readmeio/api-explorer that referenced this pull request Jun 15, 2018
…chema-form's dereferencing instead

This gets a little bit messy because you can do these 3 different types of refs for request bodies:

- inline schema
- $ref directly to a schema
- $ref to a request body object, which contains the schema within a mime type object

The first 2 work in react-jsonschema-form (after this has been merged rjsf-team/react-jsonschema-form#954)

The 3rd one doesn't, and probably never will as it's far too specific to be merged into that module. So in the case where
it is referencing a request body in components, I've switched to performing a single lookup there to fetch the actual schema
$ref (or inline schema)
@domharrington
Copy link
Contributor Author

Tests are passing locally on my machine. Anyone know why it would be failing the prettier checks for a file i have not modified?

@jbadeau
Copy link

jbadeau commented Nov 7, 2018

@domharrington we are also considering generating forms from OpenAPI. DO u have an example somewhere?

@domharrington
Copy link
Contributor Author

Yes! We're doing it quite successfully over here: https://github.com/readmeio/api-explorer

Demo site: https://preview.readme.io/

@jbadeau
Copy link

jbadeau commented Nov 7, 2018

Dude, looks verrrry interesting. Gonna have a look then get back to you. Looks very close to what Im thinking about.

@domharrington
Copy link
Contributor Author

If you're interested in a hosted solution for your docs, you should check out ReadMe: https://readme.io/. The API explorer that I linked to above is our open source project, but we have a whole host of other features built into the product including suggested edits for your docs, an API, user login with variables.

I'm an engineer at ReadMe, please feel free to reach out to me dom[at]readme.io if you have any more questions.

@glasserc
Copy link
Contributor

glasserc commented Nov 9, 2018

Hey, sorry for not responding to this at the time.

You only change the regular expression not to start with definitions, but all definitions are still looked up starting from the schema definitions, so e.g. #/components/schema/address pulls stuff out of #/definitions/components/schema/address.

To be honest, we handle definitions specially but I'm not sure if we need to. If they're true JSON pointers, they should be resolvable against the schema root. Maybe we should be passing that around instead.

Edit: any reason why you dont commit the package-lock.json file?

I'll admit ignorance here, but the reason is that rjsf is a library rather than an application, so constraining packages should happen in the calling code.

[Edit: I guess this is what I get for replying to months-old comments. We have a package-lock.json file now.]

Edit 2: also, is there any main reason (apart from keeping the repo clean) why you don't commit the built source files (in lib/ and dist/?) This makes it tricky to npm install from a fork, as lib/index.js doesn't exist in git.

As you say, it's just to keep the repo clean.

@domharrington
Copy link
Contributor Author

Hey! No worries. I made the definitions part of the regex optional because the refactor to change everywhere else in the code and examples to not start with definitions, plus it probably would constitute a major version bump to do so.

This change just allowed the possibility for it to not have to start with definitions. We're rendering OAS files, and it's much easier to just patch on the components object directly onto each schema than it is to recursively crawl the object for all $refs and modify them all to start with definitions.

Hope that makes it a little clearer for the reasoning for this change. I'm using a fork of this library currently but it would be great to get back onto the main repo. I've got one more PR too: #1001.

Thanks in advance.

@glasserc
Copy link
Contributor

I think no longer treating definitions as special but just resolving JSON pointers against the root of the schema is largely backwards-compatible. Schemas that used to work should continue to work, for instance. I think the only user-facing place where we use definitions is in registry, and I think we could produce a backwards-compatible way to manage that (combine the user's schema and definitions using realSchema = {...schema, definitions: registry.definitions}). I know that would be more work, but I think it would be much clearer than having a regexp with an optional string buried deep in the code, plus I think it would be cleaner for your use case. What do you think?

domharrington added a commit to readmeio/api-explorer that referenced this pull request Dec 12, 2018
…til edited

You can test this locally here: http://localhost:9966/?selected=swagger-files%2Ftypes.json
Search for "default value" and see that it is already in the code sample.

This issue luckily got fixed upstream:
rjsf-team/react-jsonschema-form#1034

So to bring that in I needed to update my fork of the module.

I would love to get off of my fork and get back onto the main release,
but there's some outstanding work on my PR which means we can't right now:
rjsf-team/react-jsonschema-form#954
Copy link
Member

@epicfaace epicfaace left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@domharrington , thanks for the PR; I think the approach @glasserc mentioned makes the most sense (i.e. doing #/components/abc should reference the object with the path components.abc in the schema, not definitions.components.abc).

Would you be able to modify your PR to have that behavior -- and would that behavior suffice for your needs for your own project?

package.json Outdated
@@ -16,8 +16,8 @@
"publish-to-npm": "npm run build:readme && npm run dist && npm publish",
"preversion": "npm run build:playground && npm run dist && npm run build:readme && npm run cs-check && npm run lint",
"start": "node devServer.js",
"tdd": "cross-env NODE_ENV=test mocha --require babel-register --watch --require ./test/setup-jsdom.js test/**/*_test.js",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the changes for mocha config, but can you please remove these changes from this PR and make a separate PR for it?

@domharrington
Copy link
Contributor Author

Hey @epicfaace yup i agree with everything that was said before. It's on my todo list to update this PR with the more generic solution, i've just not had the capacity to get round to it yet.

@epicfaace
Copy link
Member

This PR fixes #988 .

@domharrington
Copy link
Contributor Author

domharrington commented Feb 15, 2019

I took a stab at finishing this off today in a fresh fork from master but kept hitting upon problems around this block here: https://github.com/mozilla-services/react-jsonschema-form/blob/bece2a5a847e216c2386d4f7f0ce9cf25b549562/src/utils.js#L402-L404

Since the $ref and the definitions are coming from the same object now, it appears to get stuck in an infinite loop during that while block. E.g.

const schema = {
  definitions: {
    testdef: { type: "string" },
  },
  $ref: "#/definitions/testdef",
};

The code attempts to resolve the $ref before it gets to the point where it looks in the current object: https://github.com/mozilla-services/react-jsonschema-form/blob/bece2a5a847e216c2386d4f7f0ce9cf25b549562/src/utils.js#L405

Can anyone with more knowledge of this code point me in the right direction or suggest a way forward?

@domharrington
Copy link
Contributor Author

Hey @epicfaace, any suggestions on a way forward for this? This PR as it is is backwards compatible and though it's not completely ideal, when I tried to refactor completely I came up against some issues.

@minhnq013
Copy link

Anyone know what's the status for this one?
I have several schemas that are un-usable due to this.

Thanks

@domharrington
Copy link
Contributor Author

I'm using a fork of this module, which only has this change. You can use it by running this command:

npm i "github:domharrington/react-jsonschema-form#dist-committed"

@epicfaace
Copy link
Member

epicfaace commented Apr 22, 2019

I took a stab at finishing this off today in a fresh fork from master but kept hitting upon problems around this block here:

@domharrington Can you share the code for the approach you tried? I'm trying to understand what was your approach there. I'm thinking that a successful approach might need to make findSchemaDefinition accept the entire schema object rather than the definitions object.

I'm not comfortable with the way it's implemented now, because having #/components/schemas/address actually point to #/definitions/components/schemas/address seems to be unintuitive.

@domharrington
Copy link
Contributor Author

It's been over 2 months since I attempted it, so the code I put together at the time is probably lost to the ether or in a git stash somewhere, so I cannot remember what I tried.

The fix I implemented makes having definitions completely optional in the $ref path, it doesn't have it present in one place whilst actually pointing somewhere else. It's a backwards compatible fix

@domharrington
Copy link
Contributor Author

Any insight you can give into getting this merged would be amazing! I couldn't figure it out at the time.

@epicfaace
Copy link
Member

Hmm, not sure, will look into it and let you know

@erunion
Copy link
Collaborator

erunion commented Jul 26, 2019

@epicfaace @glasserc Is there anything else that needs to be done to this PR before it gets merged in?

@epicfaace
Copy link
Member

Closing this in favor of #1506 .

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

Successfully merging this pull request may close these issues.

6 participants