Is there a way to expand references in Swashbuckle to provide inline schemas? - .net-core

Is there a mechanism in Swashbuckle that can prevent definitions from being created with referencing to them in parameters/responses/etc.?
By default, you might get a path that looks like this:
"/profile": {
"get": {
"summary": "Get my profile details.",
"produces": [
"application/json",
],
"parameters": [],
"responses": {
"200": {
"description": "Success",
"schema": {
"$ref": "#/definitions/ProfileModel"
}
}
}
}
}
But what I'd like is for it to expand the schema inline like this:
"/profile": {
"get": {
"summary": "Get my profile details.",
"produces": [
"application/json",
],
"parameters": [],
"responses": {
"200": {
"description": "Success",
"schema": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "id"
},
"firstName": {
"type": "string",
"description": "firstName"
},
"surname": {
"type": "string",
"description": "surname"
},
"emailAddress": {
"type": "string",
"description": "emailAddress"
}
}
}
}
}
}
}
I reviewed this StackOverflow question and I don't think it's what I'm looking for (or maybe misinterpreted).
Taken a look through the Swashbuckle README to understand its capabilities but coming up short. Any help here would be most appreciated.
For additional context, looking at the Swashbuckle PDF documentation in section 1.7, I essentially want to bypass or revert the action they describe as
automatically generating a corresponding schema for user-defined reference types and reference the definition via the $ref keyword.

Digging into the codebase a little, it looks like it's not possible at the moment.
However, you can create a custom ISchemaGenerator from the one in source and alter the GenerateConcreteSchema method under the DataType.Object case to not return as reference and this solves the issue.

Related

Swagger Schema error should NOT have additional properties

I am trying to create swagger json and trying to check it's validity in
http://editor.swagger.io
Upon validating the json, the above mentioned editor gives the following error:
Schema error should NOT have additional properties
additionalProperty: components
Jump to line 0
If for some reason I can't define an element named components at root level where i am going to have some sort of json schema, what is the right way to do a $ref on the schema for requestBody for an API operation as I intend to do as seen in my example below. Also, do you see anything wrong with my swagger json ?
My swagger json for swagger2.0 look like this.
{
"swagger": "2.0",
"info": {
"version": "1.0",
"title": "My swagger API",
"contact": {
"name": "myName",
"email": "abc#gmail.com"
}
},
"host": "localhost:1234",
"basePath": "/",
"tags": [{
"name": "someTagName",
"description": "this is a try"
}],
"components":{"schemas": {"myEndPoint": ""}},
"paths": {
"/myEndPoint": {
"post": {
"tags": ["some-tag"],
"summary": "myEndPoint endpoint will give you something",
"description": "some description will go here",
"operationId": "getMyEndPoint",
"consumes": ["application/json"],
"produces": ["application/json"],
"parameters": [{
"in": "body",
"name": "somePayload",
"description": "somePayload is what this is",
"required": true,
"schema": {
"$ref": "#components/schemas/myEndPoint"
}
},
{
"in": "header",
"name": "Authorization",
"description": "auth token goes here",
"required": true,
"type": "string"
}],
"responses": {
"200": {
"description": "Success",
"schema": {
"type": "string"
}
},
"400": {
"description": "Bad Request"
}
}
}
}
}
}
You are mixing up OpenAPI 3.0 and 2.0 syntax. The components keyword is used in OpenAPI 3.0. In OpenAPI/Swagger 2.0, reusable schemas live under definitions:
"definitions": {
"myEndPoint": {
...
}
}
Make sure to also change the $ref to
"$ref": "#/definitions/myEndPoint"

copyIndex() inside a listKeys()

We're trying to deploy an ARM template which deploys a Stream Analytics job with n Event Hubs outputs depending on an input parameter.
Right now we're having success with all but the listKeys() function inside the outputs property copy loop function which gets each Event Hub's primary keys:
"sharedAccessPolicyKey": "[listKeys(resourceId('Microsoft.EventHub/namespaces/eventhubs/authorizationRules', variables('clientEventHubNamespace'), parameters('clients')[copyIndex('outputs')].id, variables('clientEventHubClientSharedAccessName')), '2015-08-01').primaryKey]"
We get the error:
17:44:31 - Error: Code=InvalidTemplate; Message=Deployment template
validation failed: 'The template resource
'tailor-router-axgf7t3gtspue' at line '129' and column '10' is not
valid: The template function 'copyIndex' is not expected at this
location. The function can only be used in a resource with copy
specified. Please see https://aka.ms/arm-copy for usage details..
Please see https://aka.ms/arm-template-expressions for usage
details.'.
However, if we change this to be a specific index:
"sharedAccessPolicyKey": "[listKeys(resourceId('Microsoft.EventHub/namespaces/eventhubs/authorizationRules', variables('clientEventHubNamespace'), parameters('clients')[0].id, variables('clientEventHubClientSharedAccessName')), '2015-08-01').primaryKey]"
it works.
Is copyIndex('propertyName') inside a listKeys() a supported function?
If not, is there a workaround that would achieve the same effect?
Kind regards,
Nick
Stream Analytics job resource definition:
{
"apiVersion": "2016-03-01",
"type": "Microsoft.StreamAnalytics/StreamingJobs",
"name": "[variables('routerStreamAnalyticsName')]",
"location": "[variables('location')]",
"dependsOn": [ "clientsEventHubCopy" ],
"tags": {
"boundedContext": "[variables('boundedContextName')]"
},
"properties": {
"sku": {
"name": "[parameters('routerStreamAnalyticsSkuTier')]"
},
"outputErrorPolicy": "drop",
"eventsOutOfOrderPolicy": "adjust",
"eventsOutOfOrderMaxDelayInSeconds": 0,
"eventsLateArrivalMaxDelayInSeconds": 5,
"dataLocale": "en-US",
"compatibilityLevel": "1.0",
"inputs": [
{
"name": "input0",
"properties": {
"type": "stream",
"serialization": {
"type": "Avro"
},
"datasource": {
"type": "Microsoft.ServiceBus/EventHub",
"properties": {
"serviceBusNamespace": "[parameters('input0EventHubNamespace')]",
"sharedAccessPolicyName": "[parameters('input0EventHubSharedAccessPolicyName')]",
"sharedAccessPolicyKey": "[parameters('input0EventHubSharedAccessPolicyKey')]",
"eventHubName": "[parameters('input0EventHubName')]"
}
}
}
}
],
"transformation": {
"name": "routing",
"properties": {
"streamingUnits": "[parameters('routerStreamAnalyticsSkuTier')]",
"query": "omitted"
}
},
"copy": [
{
"name": "outputs",
"count": "[length(parameters('clients'))]",
"input": {
"name": "[parameters('clients')[copyIndex('outputs')].id]",
"properties": {
"datasource": {
"type": "Microsoft.ServiceBus/EventHub",
"properties": {
"serviceBusNamespace": "[variables('clientEventHubNamespace')]",
"sharedAccessPolicyName": "[variables('clientEventHubClientSharedAccessName')]",
"sharedAccessPolicyKey": "[listKeys(resourceId('Microsoft.EventHub/namespaces/eventhubs/authorizationRules', variables('clientEventHubNamespace'), parameters('clients')[copyIndex('outputs')].id, variables('clientEventHubClientSharedAccessName')), '2015-08-01').primaryKey]",
"eventHubName": "[parameters('clients')[copyIndex('outputs')].id]"
}
},
"serialization": {
"type": "Avro"
}
}
}
}
]
}
},
Thanks for reporting this and sorry for the inconvenience.
I just talked to the ARM team, we had an issue when copyindex was inside the index tags eg 'array[copyindex()]'. It should be fixed now.
Let us know how it goes.
Thanks,
JS - Azure Stream Analytics

Swagger validation error on path item: "Additional properties not allowed"

I am using https://www.npmjs.com/package/swagger and I am trying to create a config. I have such a part of my swagger.js
"dummy\/{id}\/related_dummies": {
"get": {
"tags": [
"RelatedDummy"
],
"operationId": "get_by_parentRelatedDummyCollection",
"produces": [
"application\/ld+json",
"application\/hal+json",
"application\/xml",
"text\/xml",
"application\/json",
"text\/html"
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"type": "integer"
}
],
"summary": "Retrieves the collection of RelatedDummy resources.",
"responses": {
"200": {
"description": "RelatedDummy collection response",
"schema": {
"type": "array",
"items": {
"$ref": "#\/definitions\/RelatedDummy"
}
}
}
}
}
But when I run swagger validate swagger.js I keep getting this error:
Project Errors
--------------
#/paths: Additional properties not allowed: dummy/{id}/related_dummies
Results: 1 errors, 0 warnings
What could be the reason of the error? Thanks
The problem is that the path dummy/{id}/related_dummies doesn't begin with a slash.
To be recognized as a valid path item object, it needs to be /dummy/{id}/related_dummies.
Using the escaped syntax from your example, the name should be "\/dummy\/{id}\/related_dummies"
The relevant part of the Swagger–OpenAPI 2.0 specification is in the Paths Object definition.

JSONAPI - Difference between self and related in a links resource

Why is the self and related references different in the below JSONAPI resource? Aren't they pointing to the same resource? What is the difference between going to /articles/1/relationships/tags and /articles/1/tags?
{
"links": {
"self": "/articles/1/relationships/tags",
"related": "/articles/1/tags"
},
"data": [
{ "type": "tags", "id": "2" },
{ "type": "tags", "id": "3" }
]
}
You can read about that here: https://github.com/json-api/json-api/issues/508.
Basically, with /articles/1/relationships/tags response will be object which represents relationship between articles and tags. The response could be something like this (what you put in your question):
{
"links": {
"self": "/articles/1/relationships/tags",
"related": "/articles/1/tags"
},
"data": [
{ "type": "tags", "id": "2" },
{ "type": "tags", "id": "3" }
]
}
This response gives only the necessary data (in primary data attribute - data) to manipulate the relationship and not resources connected with relationship. That being said, you'll call /articles/1/relationships/tags if you want to create new relationship, add a new tag (basically updating relationship) to article, read which tags belong to article (you only need identity to search them on server) or delete article tags.
On the other hand, calling /articles/1/tags will respond with tags as primary data with all the other properties that they have (articles, relationships, links, and other top-level attributes such include, emphasized text, links and/or jsonapi).
They are different. Here is an example from my project.
Try Get http://localhost:3000/phone-numbers/1/relationships/contact you will get response like this:
{
"links": {
"self": "http://localhost:3000/phone-numbers/1/relationships/contact",
"related": "http://localhost:3000/phone-numbers/1/contact"
},
"data": {
"type": "contacts",
"id": "1"
}
}
You didn't get the attributes and relationships which is probably you want to retrieve.
Then
Try Get http://localhost:3000/phone-numbers/1/contact you will get response like this:
{
"data": {
"id": "1",
"type": "contacts",
"links": {
"self": "http://localhost:3000/contacts/1"
},
"attributes": {
"name-first": "John",
"name-last": "Doe",
"email": "john.doe#boring.test",
"twitter": null
},
"relationships": {
"phone-numbers": {
"links": {
"self": "http://localhost:3000/contacts/1/relationships/phone-numbers",
"related": "http://localhost:3000/contacts/1/phone-numbers"
}
}
}
}
}
You can see you retrieved all the information you want, including the attributes and relationships.
But you should know that relationships can be used for some purpose. Please read http://jsonapi.org/format/#crud-updating-to-one-relationships as a sample.

Strongloop loopback: how to set up a model to store multimedia?

Could someone give me an example of a model named "Multimedia.json" that I could use to store uploaded multimedia files (audio, video, or jpg)? Specifically, is there a type called "multimedia" or "binary"? Any strategies the Strongloop way?
Thanks,
{
"name": "Multimedia",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"title": {
"type": "string",
"required":true
},
"description": {
"type": "string"
},
"category": {
"type": "string" ---can this be a type called binary?
}
},
"validations": [],
"relations": {
"report": {
"type": "belongsTo",
"model": "Report",
"foreignKey": ""
}
},
"acls": [],
"methods": []
}
There is no built in way to do this, but StrongLoop themselves refer to this post in their documentation for the current best method to store metadata with the storage component.
https://stackoverflow.com/a/31118294/1753891
https://docs.strongloop.com/display/public/LB/Storage+component

Resources