I actually just built a sample that uses this, you can find it here. It was written in C#, and requires at least the 2.0.1 version of T-Rex library for metadata generation.
In terms of the raw swagger, here is what the paths would look like (/api/contacts/{name} is the actual operation, /api/contacts/schema is used to lookup the schema). Things to note would be:
- The main operation has a parameter named contactType. It is based on this parameter that a schema will be chosen for the output. There is one schema for Email addresses, and a different schema for phone numbers.
- The type returned from the main operation which points to #/definitions/ContactInfo elsewhere in the swagger
- The operation id of the schema lookup operation is GetContactInfoSchema (this will be important later), and it requires a parameter named type (also important later)
"paths": {
"/api/contacts/{name}": {
"get": {
"tags": [
"DynamicSchemas"
],
"summary": "Get Contact Info",
"description": "Gets contact info of the specified type",
"operationId": "GetContactInfo",
"consumes": [],
"produces": [
"application/json",
"text/json",
"application/xml",
"text/xml"
],
"parameters": [
{
"name": "name",
"in": "path",
"required": true,
"type": "string",
"x-ms-summary": "Contact Name"
},
{
"name": "contactType",
"in": "query",
"description": "Try either \"Phone\" or \"Email\"",
"required": true,
"type": "string",
"x-ms-summary": "Contact Type"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/ContactInfo"
}
},
"400": {
"description": "Invalid type specified"
},
"default": {
"description": "OK",
"schema": {
"$ref": "#/definitions/ContactInfo"
}
}
},
"x-ms-visibility": "important"
}
},
"/api/contacts/schema": {
"get": {
"tags": [
"DynamicSchemas"
],
"summary": "GetContactInfoSchema",
"operationId": "GetContactInfoSchema",
"consumes": [],
"produces": [
"application/json",
"text/json",
"application/xml",
"text/xml"
],
"parameters": [
{
"name": "type",
"in": "query",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "object"
}
},
"400": {
"description": "Invalid type specified"
},
"default": {
"description": "OK",
"schema": {
"type": "object"
}
}
},
"x-ms-visibility": "internal"
}
},
Now none of this would mean anything without the x-ms-dynamic-schema vendor extension being present on the type definitino that was referenced by our main operation. Which type definition? #/definitions/ContactInfo of course. So what is in the definitions section of the swagger for that?
- Within the x-ms-dynamic-schema section, it points to the operation id of the schema lookup operation.
- In the parameters section is a mapping of the parameters of that operation. As we saw above it took in a parameter named type, so there that parameter is called out. If we were going to hard code the value, we could just say "type": "somevalue". But since we are mapping that to a parameter used for our main operation, we have an object assigned instead with a property named parameter (to indicate that this is a parameter mapping), and a value of contactType (which matches the parameter name of the main operation).
- For the value-path we see schema. That's because of the shape of the output from the GetContactInfoSchema operation (we'll get to that next)
"definitions": {
"ContactInfo": {
"type": "object",
"properties": {},
"x-ms-dynamic-schema": {
"operationId": "GetContactInfoSchema",
"parameters": {
"type": {
"parameter": "contactType"
}
},
"value-path": "Schema"
}
},