-
Notifications
You must be signed in to change notification settings - Fork 15
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
Need a way to accommodate reusable YAML without violating schema or cluttering JSON #107
Comments
The problem I see with YAML anchors is several fold:
I think item 3 is very important. The JSON pointer DOES encourage both DRY and reuse, because the locations and resolution are constrained by the schema. So I could make everyone crazy by using anchors to refer to a parameter description. But json pointers will let the unit of reuse be something more predictable. Perhaps there's a way to mix the JSON pointer idea into a YAML syntax that makes sense. I don't know if YAML anchors are a good idea, though. |
I don't see the right answer yet. I will try to state the problem more succinctly, howeve… It sucks to have to write the same thing over and over again, such as What do you suggest, @fehguy ? |
OK I've hit a snag. We can allow references as such: "/pets/{id}": {
"get": {
"description": "Returns pets based on ID",
"summary": "Find pets by ID",
"operationId": "getPetsById",
"parameters": [
{ "$ref": "#/definitions/skipParam" },
{ "$ref": "#/definitions/limitParam" }
], however, we cannot define a I see a couple of options.
@earth2marsh thoughts? |
Please see the modified schema for parameters: https://github.com/fehguy/swagger-spec/blob/master/schemas/v2.0/schema.json#L148-L167 and definitions https://github.com/fehguy/swagger-spec/blob/master/schemas/v2.0/schema.json#L516-L525 |
@fehguy @earth2marsh I have been working on a few different models and hit this concern. My preference is to have a top-level 'parameters' section that can be validated against the parameter schema and if needed individual parameter definitions can reference the models in 'definitions'. That way if you want to reuse a model for multiple parameters you can do that. Although this may make Jeremy cringe... WDYT? |
@jwest-apigee @earth2marsh two thoughts.
Thinking about it more, I think that's much cleaner, and more extensible. |
I understand the benefit of having parameters in /definitions and it is definitely a valid approach. However, I like having parameter definitions in #/parameters such that it can be clean and explicit. It makes tooling easier since it is explicit where to find the model for which type of 'thing'. It is much easier to validate, semantically and structurally. It may also be easier to understand for newcommers to Swagger. Also, the model for a request/response is basically free-form and used by the API implementation being described. The model/schema for the structure of a parameter within a Swagger doc is more strict, used within the context of the Swagger doc and we expect certain fields to be there that are not used by the API implementation. |
Here is an example of how I envision it working: swagger: 2
info:
title: Petstore Sample API
description: A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification
version: 1.0.0
termsOfService: Do whatever you want with this
license:
name: MIT
url: "http://github.com/gruntjs/grunt/blob/master/LICENSE-MIT"
consumes:
- application/json
paths:
/pets/{petId}:
get:
description: Specific image for a specific pet
parameters:
- $ref: "#/parameters/petId"
required: true
responses:
"200":
description: to test 200
default:
description: to test default
/pets/{petId}/images:
get:
description: "All images for a pet"
parameters:
- $ref: "#/parameters/petId
required: true
responses:
"200":
description: to test 200
default:
description: to test default
/pets/{petId}/images/{imageId}:
get:
parameters:
- $ref: "#/parameters/petId"
required: true
- name: imageId
required: true
description: Specific image for a specific pet
responses:
"200":
description: to test 200
schema:
$ref: petImage
default:
description: to test default
parameters:
petId:
name: petId
in: path
description: "The UUID of a Pet"
definitions:
petImage:
required:
- imageId
properties:
imageId:
type: string
description: Unique entity ID
|
understood. I'm guessing that's the simplest way to go |
updated here: |
👍 |
OH now we are back to We need to advise API composers that the shortcut for In @jwest-apigee's example, we can't do the following, right? ...
paths:
/pets/{petId}:
get:
description: Specific image for a specific pet
parameters:
- $ref: petId
required: true
... |
no, we've undone that. there are two things: EDIT: should be
please see this example: |
Also, can
|
not quite, it will look like this: parameters:
- $ref: "#/parameters/skipParam"
- $ref: "#/parameters/limitParam" note: no overriding a referenced parameter |
@fehguy it should also be possible to say:
… right? I love having a top level … continuing the logic, we also have a mechanism for defining parameters in the |
Now that we are at it, let's make one for |
@earth2marsh @mohsen1 lets open up separate issues for those things and close this one to keep it clean and focused :) |
@mohsen1 I'm ok with co-mingling |
note, you can also do this: parameters:
- $ref: http://yourcompany.com/definitions/skipParam
- $ref: http://yourcompany.com/definitions/limitParam the reference to |
Do we need the
Also, is it possible to make a parameter required at the definition level and then override it in the method? (I believe, yes) |
@jwest-apigee @fehguy See https://gist.github.com/earth2marsh/264123aefc2e29551d9d#file-uber-yaml-L130 for an example using Uber. Two things to notice:
|
#/parameters/{name} refers to the element in the YAML document structure whereas ‘name: petId’ refers to the content that is interpreted by the tooling, no? I believe ‘required’ only applies to the place where it is used, not necessarily globally. Jeff West | Products | apigee | m: +1.214.450.9378 | twitter @jeffreyawest @apigee | Skype jeffrey.a.west On Sep 3, 2014, at 2:19 PM, Marsh Gardiner [email protected] wrote:
|
@jwest-apigee has a good point. Unfortunately JSON-Schema's #....
parameters:
- $ref: required_foo
parameters:
required_foo:
in: query
type: number
required: true
description: A foo. I personally don't like it. Any better solutions? |
One solution is to put #...
parameters:
- $ref: "start_latitude"
- $ref: "start_longitude"
requiredParams:
- start_latitude
- start_longitude
parameters:
start_latitude:
in: query
type: number
description: Latitude component of start location.
start_longitude:
in: query
type: number
description: Longitude component of start location. |
see my previous example (snippet below). the point of the $ref is to have one definition of that parameter. Sometimes it may be required, sometimes not - therefore it doesn't make sense to me to include it in the #/parameters/petId section. /pets/{petId}/images/{imageId}:
get:
parameters:
- $ref: "#/parameters/petId"
required: true
/pets/{petId}/something_else:
get:
parameters:
- $ref: "#/parameters/petId"
required: false
parameters:
petId:
name: petId
in: path
description: "The UUID of a Pet"
|
We can make this work: - $ref: "#/parameters/petId"
required: true But then it's not following JSON Schema standard. that YAML translated to JSON is this: {
"$ref": "#/parameters/petId",
"required": true
} JSON-Schema says you need to replace the object with it's |
I see. We’re in a difficult spot with the stage this change is being made in with regard to tooling. Given that this doesn’t work it looks like we need an alternative that we can agree on quickly. Thoughts, @fehguy? @earth2marsh? Jeff West | Products | apigee | m: +1.214.450.9378 | twitter @jeffreyawest @apigee | Skype jeffrey.a.west On Sep 3, 2014, at 2:53 PM, Mohsen Azimi [email protected] wrote:
|
Yes, you cannot merge the Think of the json pointers as just that--simply pointers, not mix-ins. |
Might not work… but what about some riff on:
|
That's the same as my proposal. The problem is, it's not following semantic hierarchy the rest of the document is following. |
cascading will mean "detailed object clobbers general object", not a merge. In the long run, this will be much better than complex merge strategies. |
@earth2marsh, @mohsen1 - Is this still an open issue? |
It sounds like you're forcing me to read the issue ;) |
@earth2marsh - ok, that was a bit TLTR but I think I managed to get the gist of it. It looks like the original issue of references for parameters (and responses) has been added. |
A benefit of YAML is that you can define a snippet of YAML once and refer back to it in many places.
However, that snippet is converted into JSON and then triggers a schema violation. Perhaps we should contain all snippets in a parent, such as
snippets
and then add that as an object in the JSON-schema. Furthermore, we should consider stripping the snippet element from the rendered JSON.Here is an example:
The text was updated successfully, but these errors were encountered: