Swagger/OpenAPI ResponseBodies Parameter with Slight Variances - swagger

How can I change one part of the $ref, or add to it?
I have an OpenAPI 3.x response body:
ordernumber:
$ref: '#/components/requestBodies/ordernumber'
The descriptive text is applicable to every instance I use this in, except for the last line. That changes for each product, like a product number.
There are similar questions but about schemas that don't seem to apply, neither do the anyof operators. I'd guess it should be like this, but of course, this doesn't work since no additional operation can be used with $ref.
ordernumber:
$ref: '#/components/requestBodies/ordernumber'
description: For all units number T100-T1200.

this doesn't work since no additional operation can be used with $ref.
Your example will work in OpenAPI 3.1 (new version released on February 16, 2021). OAS 3.1 supports having a description alongside $ref. In case of non-schema $refs, the adjacent description is supposed to override the description defined in the referenced component (if any).

Related

Swagger 2 or 3 for Spring Data Rest

I have a spring boot application using spring data rest. I have a problem in providing a well read API documentation using swagger. I tried spring fox and springdoc, but each has its problems
Spring fox:
I can not change the tag name of a repository, only the description
No support for projections
No support of openAPI3 yet (this is actually not a big problem)
Springdoc (https://springdoc.org/)
I can not change neither the tag name nor the description (#Tag does not work on repos)
No support for projections
The same repo gets 3 tags e.g. books-entity-controller, books-search-controller (with methods of a parent class) and books-property-reference-controller (with unnecessary listing of /{id}/{property} urls)
Any better way? I like spring fox for not providing more than one tag, also the auto generated tag names are better e.g. Books Entity instead of books-entity-controller. But it would be better either to customize it or find a better alternative.
I recommand Spring REST Docs over Swagger. Spring REST Docs is test-driven to guarantee your API documentation is always sync with your API.
Andy's talk explains more why Spring REST Docs is more suitable than Swagger for API documentation.
You can find offical simple guide and more samples.
My Github project uses it. You can clone the repository and have a look at the generated documentation HTML /sga-booking/index.html.
Related Spring REST Docs file are
FltApiDocumentation.java
flts.adoc
BookingApiDocumentation.java
booking.adoc
If you find my Github useful, consider give it a star.
Springdoc
I can not change neither the tag name nor the description (#Tag does not work on repos)
and
The same repo gets 3 tags
You can customize it. Use the following at the controller-class level.
#Tag(name = "Name of the Tag", description = "Description of the tag")
or
#Tags(value = {
// Multiple #Tag annotations separated by comma ,
})
or the following at the method level.
#Operation(tags = {"Tag 1", "Tag 2"})
Remember:
#Tag at a class level will override the operation level tags for the particular class.
A class level tag can have only 1 value.
So if you need a controller to have multiple tags, you should isolate it in a different class that doesn't have the #Tag at the class level.
No support for projections
I have never used projections. I generally use the #JsonIgnore to eliminate the ones not needed, but depends on your use-case.
If you want to hide something from a schema, use can use the below method
#Schema(description = "Example POJO to demonstrate the hidden attribute")
class Example {
...
#Schema(hidden = true) // <--- Will be hidden from the Swagger UI completely
String exampleId;
...
}
Hope that helps. Drop a comment for any clarification.

How to get proper results for these queries?

Need to execute and return 1st order detail alone for each order. Below doesn't work
https://services.odata.org/Experimental/Northwind/Northwind.svc/Customers?$expand=Orders($expand=Order_Details;$top=1)
Need to filter records based on order id. Below doesn't work and throws "Term 'Orders($expand=Order_Details)$filter=OrderID eq '10643'' is not valid in a $select or $expand expression"
https://services.odata.org/Experimental/Northwind/Northwind.svc/Customers?$expand=Orders($expand=Order_Details)$filter=OrderID eq '10643'
Invalid but returned results
https://services.odata.org/Experimental/Northwind/Northwind.svc/Regions?expand=Order_Details
https://services.odata.org/Experimental/Northwind/Northwind.svc/Regions?expand=Territories
Not Returning Childrens
https://services.odata.org/Experimental/Northwind/Northwind.svc/Products?&expand=Suppliers
https://services.odata.org/Experimental/Northwind/Northwind.svc/Regions?&expand=Territories
https://services.odata.org/Experimental/Northwind is no longer 'Best Practise'
It's a bold statement, but this question proves that many advanced query features have not been fully or properly implemented in the published service.
While many developers may use it to practise OData query concepts, given that the OData implementation is largely up to the developers and the version of the packages they use, it is probably a of more commercial value if you query against a live or a dev implementation of the actual service that you want to query.
The following is an analysis of OPs queries and how to achieve the desired response according the the OData-V4 specification and verified against a deployed API that utilises the following NuGet packages:
Microsoft.AspNet.OData v7.3.0
Microsoft.OData.Core v7.6.2
The actual API that I used for testing is proprietary and cannot be published here.
According to the spec, you have to move the $top specifier to the Order_Details expansion.
https://services.odata.org/Experimental/Northwind/Northwind.svc/Customers?
$expand=Orders($expand=Order_Details($top=1))
However:
https://services.odata.org/Experimental/Northwind does not correctly implement $top query option within expansion as defined in 5.1.3 System Query Option $expand
Query options can be applied to an expanded navigation property by appending a semicolon-separated list of query options, enclosed in parentheses, to the navigation property name. Allowed system query options are $filter, $select, $orderby, $skip, $top, $count, $search, and $expand.
$top is however supported in the ODataLib v7+ (.Net) implementation of OData v4. So the syntax is correct, but you should check with your API developers for their opinion if your queries with this syntax do not work.
NOTE: When using $top you should also use $orderbyto ensure that the query results are reliable and reproducable:
https://services.odata.org/Experimental/Northwind/Northwind.svc/Customers?
$expand=Orders($expand=Order_Details($orderby=ProductID;$top=1))
To apply multiple query options within an expansion, you must separate then with a semi-colon: ;. However that alone will not prevent other customer records from being returned, so you must also add a root level filter as well, which is complicated by the fact that Orders is a collection. We can use the any function to only return customers that have an order with the specified Id:
Also note that OrderID is numeric, so do not wrap comparison values in quotes
https://services.odata.org/Experimental/Northwind/Northwind.svc/Customers?
$expand=Orders($expand=Order_Details;$filter=OrderID eq 10643)
&$filter=Orders/any(o:o/OrderID eq 10643)
this can be further simplified using parameter alias:
https://services.odata.org/Experimental/Northwind/Northwind.svc/Customers?
$expand=Orders($expand=Order_Details;$filter=OrderID eq #orderId)
&$filter=Orders/any(o:o/OrderID eq #orderId)
&#orderId='10643'
However:
https://services.odata.org/Experimental/Northwind does not correctly implement parameter aliases so you cannot verify the alias syntax against this service.
Also note
that experimental service is not correctly applying the filter to either the root elements or the navigation collection, the syntax shown here does however work against the .Net ODataLib implementations of OData v4.
The reason that your $expand is not working is that you have left off the $ from the parameter name. The OData query interpreter only identifies query options are parameters that start with $.
Eitherway, according to the https://services.odata.org/Experimental/Northwind/Northwind.svc/$metadata#Regions, there is no Order_Details navigation property to $expand on:
<EntitySet Name="Regions" EntityType="NorthwindModel.Region">
<NavigationPropertyBinding Path="Territories" Target="Territories" />
</EntitySet>
So when you try again with the correct syntax:
https://services.odata.org/Experimental/Northwind/Northwind.svc/Regions?$expand=Order_Details
you get the expected message:
Could not find a property named 'OrderID' on type 'NorthwindModel.Region'
The second attempt will work if you put the correct $ in there for the $expand query option:
https://services.odata.org/Experimental/Northwind/Northwind.svc/Regions?$expand=Territories
The OData query parser only looks for the expected query options with the $ prefix, this allows your API logic to still process other non-OData parameters as you see fit to do so. The other parameters therefor are still HTTP Url compliant parameters, the implementation at odata.org doesn't know what to do with them and they are simply ignored.
This is just another variation on the same issue with 3, the $ is missing. (I suspect that this URL was meant to be in 3: https://services.odata.org/Experimental/Northwind/Northwind.svc/Products?$expand=Suppliers)
So while https://services.odata.org/Experimental/Northwind is not 100% reliable, neither are the .Net ODataLib, SAP or MS Dynamics implementations. The spec is evolving and there are many query techniques that are not fully implemented in probably any providers at this stage.
Simply be mindful of this fact and when you run into issues using an API, the first point of contact should be the developers or the community that are supporting that particular API, it will be up to the developers what techniques and packages they use and at the end of the day to what extent they support the protocol as it is specified.

Does a RFID Tag ID (TID) have a CRC?

I was looking at the GS1 Tag Data Standard and noticed the EPC has a CRC-16. However, the unique tag ID (TID), specified in Section 16, does not.
Is that the case there is no checksum on the Tag ID? If so, what is the suggested method to ensure the tag ID that is read is in fact the actual value and that no bits were flipped?
Got my answer from another message board. I'll post a summary here.
I was focused on the "StoredCRC" defined in the Memory spec mentioned above. However, I was pointed to the Air Interface spec. In there, it defines both the StoredCRC as well as the PacketCRC. The latter is used for many interrogator->tag and tag->interrogator messages.
Some notable references in that spec:
Section 6.3.1.5 gave a nice overview
Section 6.3.2.1.2.1 described how StoredCRC and PacketCRC are managed/used
Table 6.17 and Table 6.28 were good examples of the structure

odata v4 search example needed

I am trying to learn the OData version 4 protocol and am using the Northwind database to run queries against.
OData 4 introduced the free text search with $search but the queries I've tried all fail.
A couple things I tried (with many variants):
http://services.odata.org/V4/Northwind/Northwind.svc/Customers?$search=%28City%20eq%20Berlin%29
http://services.odata.org/V4/Northwind/Northwind.svc/Customers?$search=City%20eq%20Berlin
http://services.odata.org/V4/Northwind/Northwind.svc/Customers?$search=Berlin
Error message I get is: The query parameter '$search' begins with a system-reserved '$' character but is not recognized.
The official docs don't say much here, and just reference another source for the exact format. However, the format is very cryptic to me...
From the docs, the general idea is http://host/service/Products?$search=blue OR green which seems in line with my examples. So not sure what I'm doing wrong here.
Has anyone successfully used this before and could give me an example? Thanks!
You got an error message from http://services.odata.org/V4/Northwind/Northwind.svc because this service has not been updated to support $search. ODL began to support $search in version 6.1.0. please check 6.1.0 release notes
From the spec, "The $search system query option restricts the result to include only those entities matching the specified search expression. The definition of what it means to match is dependent upon the implementation." Since the match rule is dependent on the service implementation, the service can determine which property or even properties combinations to match the search expression.
This service http://odatae2etest.azurewebsites.net/demo/DefaultService/ has simply implemented $search, and this service choose to have the first string type property to match the search expression.
So for this service, http://odatae2etest.azurewebsites.net/demo/DefaultService/ProductDetails?$search=snack is actually meant to return ProductDetails whose description contains 'snack'.
Otherwise, $search supports AND, OR, NOT operations.

Avoiding repeated type definition for each result when projecting in Breeze.js

I'm currently querying an Entity using projections to avoid returning the entire object.
It works flawlessly, however, when looking at the actual response from the server, I'm seeing the same type definition repeated for every single element.
For example:
["$type":"_IB_4NdB_p8LiaC3WlWHHQ_pZzrAC_plF4[[System.Int32, mscorlib],[System.String, mscorlib],[System.String, mscorlib],[System.String, mscorlib],[System.Nullable`1[[System.Int32, mscorlib]], mscorlib],[System.Int32, mscorlib],[System.Single, mscorlib]], _IB_4NdB_p8LiaC3WlWHHQ_pZzrAC_plF4_IdeaBlade"
Now, given that every item in the result is sharing the same projection for that query, is there a way to have Breeze only define the Type Description ONCE instead of for every element?
It may not seem like a big deal but as result size increases those bytes do start to add up. At the moment There is little difference between returning the projected values and the entire entity itself due to this overhead.
NOTE: As it turns out, since we use Dynamic Compression of JSON in our real environments, this actually turns out to be a minor issue, since 200KB responses actually turn into less than 20KB traffic after gzip compression. Will probably be closing this question, unless someone has something to add that could be of use to others.
Update 18 September 2014
I decided to "cure" the problem of the long ugly $type names in serialized data for both dynamic types from projection queries and anonymous types created for an endpoint such as "Lookups".
There's a new Breeze Labs nuget package, "Breeze.DynamicTypeRenaming" (search for "Breeze Dynamic Type Renaming"). This adds two files to your Web API project's "Controllers" folder. One is a CustomBreezeConfig which replaces Breeze's default config and resets the Json.Net "Binder" setting with the new DynamicTypeRenamingSerializationBinder; this binder does the type name magic.
Just install the nuget package in your Web API project and it should "just work". In your case, the $type value would become "_IB_4NdB_p8LiaC3WlWHHQ_pZzrAC_plF4, Dynamic".
See an example of it in the "DocCode" sample.
As always, this is a Breeze Lab product, not part of the core Breeze product. It is offered "as is" with no promise of support. I'm pretty sure it's good and has no adverse side-effects. No guarantees. I'm sure you'll let me know if there's a problem.
That IS atrocious, isn't it! That's the C# generated anonymous type. You can get rid of it by casting into a custom DTO type.
I don't know if it is actually harmful. I hate looking at it in any case.
Lately I've been thinking about adding a JSON.NET IContractResolver that detects such uglies and turns them into shorter uglies. Wouldn't be hard. Just haven't had the time.
Why not write that yourself and contribute to the community? We'd be grateful! :-)
Using Dynamic Compression of JSON output has turned this into a non-issue, at least for now, since all that repeated content is heavily compressed server-side.

Resources