I have a few protocols that I am trying to parse for a personal project. I realize that I could create custom code using Python's struct library or the like, but I was wondering if there was an existing library that could describe how to parse a binary payload in a more declarative manner. If I could make wishes come true the library would take some input looking like the following and generate a parser for me:
{
messageType: exampleMessage,
messageAttributes: {
endianness: little,
pack: ALIGNED},
dataStructure: [
{name: messageId, type: int16},
{name: payloadSize: type: int32},
{name: payload: type: utf_8, size: {ref: payloadSize}},
{name: checksum: type: CRC32, context: example_message}]
}
Have you tried MessagePack, it's like JSON but fast and small? It is an efficient binary serialization format. It lets you exchange data among multiple languages like JSON. But it's faster and smaller.
Related
I am trying to add multiple examples for an Object property.
The Swagger-Ui and Editor version that I am using are
'{"swaggerEditor":"3.6.31/g10642b3c-dirty","swaggerUi":{"version":"3.23.0","gitRevision":"g23d7260f","gitDirty":true,"buildTimestamp":"Sat, 29 Jun 2019 19:42:59 GMT","machine":"jenins-swagger-oss"}}'
Based on OpenAPI doc, this version of swagger UI and editor have support for multiple examples but I still see this error:
Structural error at components.schemas.MainObject.allOf.3.properties.partitionProperty
should NOT have additional properties
additionalProperty: examples
Jump to line 3016
This is how I have added the examples in the property:
MainObject:
allOf:
- $ref: '#/components/schemas/MainObjectLite'
- type: object
description: foobar.
readOnly: true
required:
- fooRequired
properties:
fooRequired:
type: string
description: system only field used for table data indexing
partitionProperty:
type: string
description: foobar
examples:
sampleExample:
value: 2016-03-04T03:00:00
summary: sample partition
OpenAPI 3.0
Multiple examples are only supported at the media type level and are not supported inside schemas. Schemas and properties can only have a single example, e.g.
partitionProperty:
type: string
example: '2016-03-04T03:00:00'
In other words, this won't work:
MainObject:
type: object
properties:
..
examples: # <--- Won't work
minimal:
summary: Minimal example
value:
foo: bar
full:
summary: Example with all properties
value:
foo: bar
baz: xyzzy
If you want multiple examples, you need to use request examples or response examples instead:
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/MainObject'
examples:
minimal:
summary: Minimal example
value:
foo: bar
full:
summary: Example with all properties
value:
foo: bar
baz: xyzzy
OpenAPI 3.1
OAS 3.1 uses a newer version of JSON Schema which supports multiple examples in schemas and properties. Unlike media type examples which is a map of named Example Objects, schema-level and property-level examples is a plain list of example values.
MyObject:
type: object
properties:
prop1:
type: string
# Property-level examples
examples:
- foo
- bar
prop2:
type: integer
# Object-level examples
examples:
- prop1: hello
prop2: 5
- prop1: world
prop2: 0
I've noticed that while Quicktype.io does a very good job of parsing JSON into SWIFt, occasionally it resorts to a lot of auxiliary functions and methods. For the following, it generated about 15 additional methods. Some of these are familiar such as NSNull, however, two are unfamiliar to me such as JSONAny and it seems like there ought to be a way around them. The JSONAny class for example, has about 12 functions in it and it is used to parse just one field that is not that important to me.
Here is what the JSON looks like:
[{"name":"Afghanistan","topLevelDomain":[".af"],"alpha2Code":"AF","alpha3Code":"AFG","callingCodes":["93"],"capital":"Kabul","altSpellings":["AF","Afġānistān"],"region":"Asia","subregion":"Southern Asia","population":27657145,"latlng":[33.0,65.0],"demonym":"Afghan","area":652230.0,"gini":27.8,"timezones":["UTC+04:30"],"borders":["IRN","PAK","TKM","UZB","TJK","CHN"],"nativeName":"افغانستان","numericCode":"004","currencies":[{"code":"AFN","name":"Afghan afghani","symbol":"؋"}],"languages":[{"iso639_1":"ps","iso639_2":"pus","name":"Pashto","nativeName":"پښتو"},{"iso639_1":"uz","iso639_2":"uzb","name":"Uzbek","nativeName":"Oʻzbek"},{"iso639_1":"tk","iso639_2":"tuk","name":"Turkmen","nativeName":"Türkmen"}],"translations":{"de":"Afghanistan","es":"Afganistán","fr":"Afghanistan","ja":"アフガニスタン","it":"Afghanistan","br":"Afeganistão","pt":"Afeganistão","nl":"Afghanistan","hr":"Afganistan","fa":"افغانستان"},"flag":"https://restcountries.eu/data/afg.svg","regionalBlocs":[{"acronym":"SAARC","name":"South Asian Association for Regional Cooperation","otherAcronyms":[],"otherNames":[]}],"cioc":"AFG"}]
I wont' give all the code that that struct is one level down from the main struct:
struct CountryReturnedElement: Codable {
//...various fields
let regionalBlocs: [RegionalBloc]
}
// MARK: - RegionalBloc
struct RegionalBloc: Codable {
let acronym, name: String
let otherAcronyms, otherNames: [JSONAny]
}
Which is designed to decode merely the following JSON:
"regionalBlocs":[{"acronym":"SAARC","name":"South Asian Association for Regional Cooperation","otherAcronyms":[],"otherNames":[]}]
Is there a simple way to parse the above without resorting to auxiliary classes with literally fifteen functions and methods. I all likelihood, otherAcronyms and otherNames are strings so I guess I could go [String?]. However, I guess I don't know that with 100% certainty, more like 95% certainty.
Thanks for any suggestions.
If you're certain the otherAcronyms and otherNames keys return [String?] you can modify the RegionalBloc struct to accept [String?].
struct RegionalBloc: Codable {
let acronym, name: String
let otherAcronyms, otherNames: [String?]
}
You can simply try it out and if the JSONDecoder doesn't throw any error you're good and can continue with [String?]. Otherwise, you can check the error and print it out onto the console to check the incoming type and set it.
I'd like to provide a series of custom codes and message for my error 400 but can't find any way to do so.
Ideally something like:
Error:
type: object
enum:
- [E01, 'Error1']
- [E02, 'Error2']
And so on
So I'm not sure that enums here can help you.
If you take a look over official documentation Enums are just strings, not object https://swagger.io/docs/specification/data-models/enums/ .
So my proposal is to use :
ErrorType:
type: object
properties:
code:
type: integer
name:
type: string
example: # Sample object
code: 10
name: Custom Error
Error:
type: object
properties:
errors:
oneOf:
- $ref '#/ErrorType'
- etc...
or directly without properties
Error:
type: object
oneOf:
- $ref '#/ErrorType'
- etc...
You can take a look for more examples on the official page https://swagger.io/docs/specification/data-models/oneof-anyof-allof-not/
You can check out how Twitter has described it with $oneOf ( https://api.twitter.com/labs/2/openapi.json ) but unfortunately this convention is not easy nor supported by code generation tools like openapi-generator.
Until OpenApi supports enum descriptions (proposal is pending), one of the easiest ways are to:
define enum with all possible error codes
in the top level description: section of the spec define an inner section (with markdown notation #Error codes) that lists all error codes along with description.
Automated tool should check if the enum and description is consistent.
I am attempting to create a relationship in my Neo4j database with a GraphQL mutation. I have a number of other mutations already working except this one causing problems. It looks like this:
mutation(
$id: String!,
$recipe: String!,
$date: String!
) {
CreateUserRecipeRelation(id:$id, recipe:$recipe, date:$date) {
id
recipe {
name
}
}
}
I am passing in the following set of parameters:
{"id": "google-oauth2|yyyyremovedauthstuffyyyy", "recipe": "baked spaghetti", "date": "10/10/2018"}
But the GraphQL playground throws the following error:
"Variable \"$id\" of required type \"String!\" was not provided."
In my schema.graphql file I have the following defined:
CreateUserRecipeRelation (
id: String
recipe: String
date: String
): User #cypher(statement:
"MATCH (r:Recipe{name:$recipe}), (u:User{id:$id}) CREATE (r)-[c:Created_By{date:$date}]->(u) RETURN r,c,u")
And if I run that cypher query directly in Neo4j it works just fine. In this same project I have 5 or 6 other relationship-creating mutations currently working but this one is giving me pause.
UPDATE:
This is a mutation I currently have that is working, so you can see the similarity in structure:
CreateIngredientRelation (
name: String
recipe: String
quantity: String
): Ingredient #cypher(statement:
"MATCH (r:Recipe{name:$recipe}), (i:Ingredient{name:$name}) CREATE (r)-[c:Contains{quantity:$quantity}]->(i) RETURN r,c,i")
This one works great and creates tons of relationships with the quantity attached to them. This is why I am puzzled. If they both didn't work it would be easier to try and come up with a solution I think.
#BehemothDan, how are you calling this mutation? Are you using react-apollo? If yes, Let me provide you an example of how you should be handling this.
For example, if you have a form to create this UserRecipeRelation. You have your Mutation component from react-apollo. On this Mutation you have on renderProps CreateUserRecipeRelation, that you could pass to a function on onSubmit. In this function you pass your variables:
UserRecipeRelation({ variables: { id: 'your id', recipe: 'bla bla', date: '12/12/18' } });
Hope it helps! :)
I want to add a description to an object property that his definition is referenced. Something like that:
newCreditCard:
type: object
properties:
billingPhone:
description: Phone number of the card holder
$ref: "#/definitions/PhoneNumber"
But the editor warns that the description property will be skipped:
Extra JSON Reference properties will be ignored: description
I have found a less elegant workaround that works for the editor, but not for the Swagger UI (not sure that is may due to the recent update to 3.0.2 version of the Swagger UI)
newCreditCard:
type: object
properties:
billingPhone:
description: Phone number of the card holder
allOf:
- $ref: "#/definitions/PhoneNumber"
How do you do it in your Swaggers specification?
Thanks for the help!
If you add anything to the same level of $ref it will be ignored .
json $ref definition https://datatracker.ietf.org/doc/html/draft-pbryan-zyp-json-ref-03#section-3
correct way is to provide the description in the referenced object.
You could simply move the description property to the definition of PhoneNumber. Your original post does not show how you have defined PhoneNumber, but this snippet validates without warnings:
definitions:
phoneNumber:
type: string
description: Phone number of the card holder
newCreditCard:
type: object
properties:
billingPhone:
$ref: "#/definitions/phoneNumber"
If this answer is not what you are looking for, please restate the question. We need to know what you are trying to accomplish.
although it is not according to JSON standards.
if you are using Swashbuckle to generate your swagger.
i took advantage over the "Extensions" property of schema.
and managed to create a swagger JSON, with $ref and extended properties.
var refSchema = new OpenApiSchema
{
//Reference = new OpenApiReference { ExternalResource = referenceLink, Type = ReferenceType.Link }, this wont work and omit all your other properties
Extensions = new Dictionary<string, IOpenApiExtension>
{
{ "$ref" , new OpenApiString(referenceLink) } // adding ref as extension cause according to JSON standards $ref shouldnt have any other properties
},
Description = prop.Value.Description,
ReadOnly = prop.Value.ReadOnly,
Required = prop.Value.Required,
Type = prop.Value.Type,
Example = prop.Value.Example,
};
For anyone using Swashbuckle with ASP.NET, you can use the following code to have the $ref construct put under the allOf (just like the :
// do this wherever you are calling AddSwaggerGen()
ArgBuilder.Services.AddSwaggerGen(opts => {
opts.UseAllOfToExtendReferenceSchemas(); // add this line.
});
Now if you have a model with two properties of the same type, the individual descriptions for each field will show up in Swagger UI (e.g. below, both FooHeader and BarHeader are properties of type HttpHeader and their descriptions show up):