Conversation
|
What if we just called it |
|
ExtractedParameter was what @davepacheco and I had landed on originally. We replaced that with JsonSchema so I figured it made sense to revive that original name. I'll defer to Dave if he prefers Extract. |
davepacheco
left a comment
There was a problem hiding this comment.
Thanks for doing this!
In terms of the name: when we were talking about this before, I'm not sure whether ExtractedParameter also referred to output types. (It's possible that it did and I didn't realize this at the time!) In this version, it definitely does: if you have a type that's returned by an API endpoint, it has to impl ExtractedParameter, which now feels like the wrong name. What about calling it Schema, since if I understand correctly, the defining property is that this thing have a way to generate a schema for itself, which might be used for input or output. dropshot::JsonSchema would probably be okay too since the schema it generates is probably specific to JSON Schema anyway.
Unrelatedly: I'm not sure about you but I'm not positive this will just work for all consumers. I don't have a specific fear in mind but I'd have more confidence if we updated oxide-api-prototype too. I'm happy to take a swing at that when we're ready here.
Lastly: we have a bunch of consumers now -- @jclulow, @jessfraz, and a few others that have filed issues. We probably want to start a changelog that documents breaking changes and how to update past them. I can take a swing at this when we're ready to publish the next version.
| * Extractors | ||
| */ | ||
|
|
||
| pub trait ExtractedParameter: JsonSchema {} |
There was a problem hiding this comment.
I'm not sure I grok this. Are these two lines saying: anything that implements ExtractedParameter also needs to impl JsonSchema, and further anything that implements JsonSchema also implements ExtractedParameter? It might be useful to add a (non-doc) comment explaining why we're doing this.
Does this get used anywhere? Is it just in trait bounds? I gather dropshot::ExtractedParameter refers to the JsonSchema derive macro, not this.
There was a problem hiding this comment.
This says:
ExtractedParameteris a subtrait ofJsonSchemathat adds nothing new- Anything that impls
JsonSchemaalso implsExtractedParameter
So then the derive macro that we export called ExtractedParamter today just is an alias for the JsonSchema derive macro, but we could change it in the future to, say, the openapiv3 definition of schemas or something compatible.
I'm note sure I completely answered your question so definitely let me know if I didn't.
| * | ||
| * /** Represents a project in our API */ | ||
| * #[derive(Serialize, JsonSchema)] | ||
| * #[derive(Serialize, ExtractedParameter)] |
There was a problem hiding this comment.
Here's the example where the thing deriving ExtractedParameter is not a parameter at all. It's an output type.
| extern crate dropshot_endpoint; | ||
| pub use dropshot_endpoint::endpoint; | ||
|
|
||
| pub use schemars::JsonSchema as ExtractedParameter; |
There was a problem hiding this comment.
Can we add a doc comment for this that explains to users what this is and when and how to use it? It doesn't need to be super detailed -- we could refer to the module level example if that makes sense. Maybe:
Derives [
ExtractedParameter] for a type, enabling Dropshot to generate a schema for the type. This must be applied to types that are used as input parameters, outputs, and anything else that might have a schema that appears in the generated OpenAPI specification. See the crate-level documentation for examples.
Similarly, I think it would help a lot to document (in a non-doc comment) what's going on here. Maybe something like:
We expose the
schemars::JsonSchemaderive macro asdropshot::ExtractedParameterso that we can leverage theschemarsimplementation without consumers having to know about that crate. This will allow us to change implementations in the future. Note that technically, this macro derives theJsonSchematrait, notExtractedParameter, butExtractedParameterprovides a blanket impl for all types that implJsonSchema. The net result is that by using thedropshot::ExtractedParametermacro, consumers get an impl of theExtractedParametertrait.
That might be too wordy -- I don't know. I think what you've done here is idiomatic (where there's a trait and a derive macro (that impls the trait) with the same name), but I find it awfully confusing when debugging compile errors. Even now, I'm not sure what I wrote is correct -- does schemars::JsonSchema refer to the macro or the trait?
There was a problem hiding this comment.
Absolutely -- my bad. Thanks for the suggested text.
Yeah, that works for me. I'll make that change.
This should be backward compatible i.e. not a breaking change. However if we ever replace That said, I'll do two experiments: |
That'd be great. I'm also happy to help. |
|
@davepacheco I forgot about this: https://github.com/oxidecomputer/oxide-api-prototype/blob/master/src/api_model.rs#L195 In the API prototype we have a custom JsonSchema for the ApiName type. I now thing the right thing is just to re-export JsonSchema and not bother with this new |
|
@davepacheco this was a great suggestion: I'm pretty convinced now that my approach is invalid. The schemars::JsonSchema derive macro emits code that explicitly references the |
|
After doing some more digging, I don't think it's going to be possible to avoid having clients 1. enumerate a dependency on
This seems to be endemic with several relevant issues open on the topic
The |
Fixes #67
This effectively aliases the
JsonSchematrait and exports theJsonSchemaderive macro under the nameExtractedParameterthis both removes the requirement that consumers depend onschemarsand would allow us to swap out something else in the future (as seems likely).I'd suggest starting with dropshot/src/handler.rs and dropshot/src/lib.rs -- the rest is basically search and replace.