Why isn't there a Swagger/OpenAPI for binary formats?
anachronauts.club
anachronauts.club
OpenAPI isn't necessarily great at this either. If your JSON API wasn't designed with OpenAPI in mind (or in a way that's similar to typical OpenAPI designs), it might not be possible to write an OpenAPI spec that describes the format well. But "type: object" is valid, so it's always possible to write a "spec".
I think the question ("why is there no schema language for binary formats?") is valid, but that OpenAPI isn't as encompassing as it's laid out to be.
OpenApi specifications that need three or four requests to reason with are a lot harder to work with than ones that are only one request, and these are different beast they become protocols. In my personal experience the binary specification often are protocols with a lot more implicit state in them, e.g. binary diff of in memory struct etc. You quickly lose the usefullness of Swagger the more state you have.
That said there are lots of good example of binary protocols that try to be stateless.
Conclussion: This blog post need to be scoped a bit better, what kind of binary communications do you want an OpenApi for and how is that different from what exists today?
As soon as you have to encode the state of the application in the specification of the protocol (like TCP above) things get really complicated.
With binary formats, on the other hand, there's neither data model nor usage constraints like that, and a generic tool to handle all the things would be just the Turing machine -- and then we have a bunch of languages for that. As for kaitai struct and similar attempts to handle arbitrary binary formats, I hear of those from time to time, and in some cases they seem to be useful, but they too should be either Turing-complete (and then it probably makes more sense to use general-purpose languages) or would fail to be useful occasionally.
Think about handling a ZIP file: you can't start at the beginning of the file and work forward from there. No; you have to start at/near the end of file and scan for an end-of-central-directory record based on a signature (it's not at a fixed offset due to a variable-length comment field). That then enables you to find the actual offset for the central directory itself; which in turns allow you to find the files themselves.
i think something very similar to kaitai could work if the tools to work with the files programmatically were ergonomic and available in many different languages. e.g., if the kaitai compiler were a native compiled library with lots of packaged FFI wrappers for many languages.
And there's indeed a practice of embedding some languages into others, though I think it ends up quite awkward to use, and in this case potential limitations (actually I don't know if kaitai is Turing-complete) may be undesirable. I imagine in many cases it may be simpler to ship, say, a parser/decoder (and/or printer/encoder) library providing a C API that is easy to call via FFI, rather than a description in a less common language, to be used with a particular library. But then again, probably that'd have its uses too.
[1] https://github.com/grpc/grpc/blob/master/doc/server-reflecti...
Can it support s-expr based formats? Plain text keyword:value pairs? Any arbitrary input? Because that's what you're asking for for "binary formats". Which is a wide-open field. To have a universal system for that you will need something closer to the parser description formats that you have already rejected. Just like you'd have to do to properly support any arbitrary plain text format instead of just JSON and XML.
Kaitai [3] mentioned by OP and sibling comments looks interesting, don’t think I’ve seen something like it before.
[1]: https://swagger.io/specification/
[3]: https://kaitai.io/
I wrote a few in Lua, but it still felt second class citizen to built-in C dissectors, loading them was annoying and the UI to use them was too.
A good dissector will annotate fields with semantic meaning and group and nest them, giving wireshark the precise bit offset+length where a value came from.
Those are some different requirements than other parsers and reuse is therefore a bit difficult.
Happened to just see this article when reading Kaitai docs: https://www.incibe-cert.es/en/blog/understanding-industrial-...
I was checking out Kaitai the other day (generate binary parsers from declarative structures) and noticed its tutorials section has great content on reverse-engineering binary formats with it: https://doc.kaitai.io. Might be interesting to anyone interested in OP's question.
I like the first blog link that reverses the binary format of one of those interactive anime novels from an .exe: https://hackernoon.com/reverse-engineering-visual-novels-101...
Really cool walkthrough of how to do such a thing regardless of whether you use Kaitai to do it.
I feel like I’ve self-promoted Restruct like four times on Hacker News, and I feel kind of bad because it could use improvements and even some bug fixes and I never seem to get around to it. Oh well. It’s still useful for me, I hope it’s useful for others, too.
That said, Kaitai has a fairly clear path towards adding serialization from a design PoV; many things that would be calculated for parsing structures in deserialization could just become checks/assertions in serialization. As an example, checking that an expression calculates out to the expected value would be a reasonable approach. Reversible expressions could be implemented for some cases, too, if you want it to do more of the heavy lifting. I think the biggest obstacle is actually implementing it, and frankly my Scala is too weak to help with such a relatively big undertaking.
I’ve also played with the rust nom library, which implements functional programming style parser combinators. It is quite cool how it can express fairly complex grammars and binary formats pretty much equally well, albeit optimizing it effectively requires serious magic that I do not think nom has. (I assume in Haskell, the same thing can be done with mind-boggling optimization power.) It also doesn’t handle serialization, but it’s still worth noting for robust deserialization.
[1]: https://github.com/go-restruct/restruct
The answer is: "The things that exist are good enough for what people are usually trying to do"
It's unclear what the author's real use case is.
The reason proto/etc suffice for most people is that they do not care about the physical format, and control it. As a result, there is no need to define it explicitly or separately, and mostly people don't care to.
The folks that need to control the physical format are often those reading other people's formats. In a lot of cases, those producing the format don't care if you can read it or not :). They are often part of some ecosystem (say, photoshop, or whatever). As a result, they wouldn't use an "openapi for binary formats" even if it existed.
For lots of other kinds of standardized formats to read (video, image, etc), these days the processing is harder than the parsing. Not that it's worth nothing, mind you, but that i doubt you would find a lot of people care enough to think it's worth it.
You also start to get into fairly different kinds of formats quickly (IE network protocol formats vs file formats), and those differences often lend themselves to different abstractions (IE you often want to be able to stream decode network formats, but may care less about stream decoding file formats, etc).
The market that remains to be served well here seems pretty small. Certainly there are folks who want to control the physical format for some reason (whether they need to or not), etc.
But again, that feels like a small fraction of cases.
As a result, nobody felt enough of a need for OpenAPI for binary formats to push very hard on it. (and attempts at doing so in the past have failed for lack of value)
I wish there was a similar tool that allowed me to simply highlight and bookmark blocks of binary data when I'm dealing with an unknown file format, such as a firmware dump for something exotic and/or proprietary.
[0] https://www.sweetscape.com/010editor/templates.html [1] https://www.sweetscape.com/010editor/
SWIG is built on top of C .h files, which are the _real_ Swagger for binary formats.
Welcome to hell, abandon all hope, etc.
Is it possible to for an application to have editable structures and KaiTai to parse them without needing to recompile the whole application (I'm speaking here in a java context).
One new project in this space is poke:
It can describe arbitrary formats for both reading and writing, and it's usable programmatically, so I think it can solve the problem!
katai allows you to declaratively define a binary format bit for bit - they even have an IDE
Is it possible to for an application to have editable structures and KaiTai to parse them without needing to recompile the whole application (I'm speaking here in a java context).
Basically Katai struct but can also be used to serialize, not just deserialize?
If your problem space is "a way to assign meaning to arbitrary bitfields", I don't feel that OpenAPI is a very good comparison. Its purview is "representing web APIs in terms of structured JSON/XML payloads". That is, OpenAPI also deals in logical and not physical representation. (unless it specifies UTF-8 or something - it might, I don't know!)
Well, it and every other binary RPC technology...