fmvilas / asyncapi-pitches Goto Github PK
View Code? Open in Web Editor NEWPitches for AsyncAPI features
Pitches for AsyncAPI features
Our current parser is tightly coupled to the AsyncAPI document structure.
Create a new parser API that represents intents instead of the structure of the document.
Tight coupling to the document structure means that if we change it, we'll be creating breaking changes in the parser too and therefore having to release a new major version.
For instance, in our current version, we grab the title of our API from the info
object:
asyncapi: 2.0.0
info:
title: My API
asyncapi.info().title()
In the future, we decide to move title
to the root of the document:
asyncapi: 3.0.0
title: My API
asyncapi.info().title()
The parser breaks because there's no such field title
inside the info
object on AsyncAPI v3. One could argue that we can make the title()
function check the version of the document and therefore look for the title in a different place, depending on the version. However, the chain asyncapi
-> info()
-> title()
suggests (and actually maps) to the structure of the document in v2.
Note this is just a simple example (and we most probably will not move the info
object anywhere anytime soon) but it's highly probable that we reorganize things on the Channel Item Object. See the following example:
asyncapi: 2.0.0
channels:
mychannel:
description: My channel description
subscribe:
message:
payload: ...
asyncapi.channel('mychannel').subscribe().message().payload()
This obtains the payload of the message people can subscribe to on the channel mychannel
. There's a high chance we'll take the operation (subscribe
) information out of this object somehow for the next version. Let's imagine the following situation:
asyncapi: 3.0.0
channels:
mychannel:
description: My channel description
message:
payload: ...
operations:
subscribeToMyChannel:
operation: subscribe
channel: mychannel
asyncapi.channel('mychannel').subscribe().message().payload()
The chain of calls asyncapi
-> channel('mychannel')
-> subscribe()
-> message()
-> payload()
doesn't make sense anymore. It will be a legacy thing from AsyncAPI v2. And we'd probably have to add a new chain of calls to match v3 structure but that actually does the same. Something like asyncapi
-> operations('subscribeToMyChannel')
-> message()
-> payload()
.
In short, every single time we change the structure of the document we're breaking the parser and the semantics of this chain of calls.
First of all, I want to make it clear that I don't want you to implement my solution. I'd love for you to come up with a better solution and implement it.
In my opinion, the problem described above comes when we couple things tightly. It's beautiful and intuitive when you know the structure or the structure doesn't change very often. So how can we design this API so it doesn't change that often? Design based on intents. Make sure you have a look around all the tools we have using the current parser and try to guess what was the intent behind.
A simple example:
asyncapi.channel('mychannel').subscribe().message().payload()
What's the intent of this call? The user wants to get the payload of the message when someone subscribes to the channel mychannel
. This could be much shorter and intuitive for the user. For instance:
asyncapi.getMessageFor('mychannel', 'subscribe').payload()
// or
const message = asyncapi.getMessageFor('mychannel', 'subscribe')
console.log(message.payload())
In the chain of calls above, there's no implicit structure mapping with the AsyncAPI document 🎉 Now, even if we change the structure of the AsyncAPI document in future versions, this will still work the same way. People will only have to upgrade their parser. That's it.
As you can see, we're focusing on intents and concepts. There will always be channels, messages, operations, and payloads. The method getMessageFor(CHANNEL, OPERATION)
expresses a clear intent and —independently of the version or structure of the document— the intent of the user will not change.
So my suggestion is that you go and define all the "concepts" we have on the spec and build a list of intents you see already happening on our tools plus others you think could be useful. A great place to look for inspiration is the Generator templates.
If you feel comfortable, go ahead and release v2-alpha, v2-beta, etc. but don't release v2 as we'll have to test it with the community properly during some time.
It's ok to open pull requests on the Generator templates that would help us migrate them in the future. In the end, you have to test the new API somewhere. Just don't consider this work part of the bet. Don't get me wrong, I highly recommend you use the new parser on two or three templates, just don't consider this migration something you have to finish in this cycle.
Current API documentation is far from perfect. We know and we'll dedicate time for it. While you have to change them to document the new API, don't go beyond that (like using other tools to generate docs, changing the structure of the docs, etc.)
It's easy to get lost in trying to make this parser perfect on the first iteration. Don't worry about perfection now because we'll have to test this with the community for some time and we'll detect new intents as we go.
As some of you may have noticed, since Swagger 2.0 was donated by Smartbear to Linux Foundation, OpenAPI 3.0.0 has been released. It happened on the 26th of July 2017. Still many people haven't migrated yet from Swagger 2.0 to OpenAPI 3.0.0. When I asked, many people told me:
It's great it's on v3 now but v2 is more than enough for me. v3 is not introducing enough value for me to switch. Also, the tooling is not yet updated so 🤷
However, v3 had a really good thing. They started moving things around the document to better suit the spec for future changes. Just like the example of channels and operations above. Moving them around don't provide much value for the end user but it does for us and it's something you have to do from time to time, especially in the early stages (yes, we're still in the early stages 😄).
One of the reasons people didn't migrate to v3 quickly was that products weren't supporting it yet. It was a huge a investment for the companies to migrate their tools to support v3 and it wasn't providing much new value to their users. The result: "yes, we'll do it but it's not a priority for us". This affected a lot the speed of adoption of OpenAPI 3.0.0. With this API design, companies should be able quickly update their parsers and start supporting new versions. The only thing they'll have to invest time on is exactly what provides value for the users: the new features.
We're currently maintaining two HTML documentation views: the HTML template and the React component.
Improve the React component so it matches the features and look & feel of the HTML template. Once it's done, make the HTML template use the React component to generate the HTML output.
While this task may sound easy, there are a bunch of small features/details that are not present in the React component:
components
.allOf
, which is an incorrect behavior.additionalItems
.We should make sure these features are present in the React component. Otherwise, people will be losing features with the switch from the HTML template to React.
When it comes to making the HTML template render the React component, my suggestion is that we have a look at the following ReactDOMServer and ReactDOM methods:
I found this article very helpful: https://dev.to/marvelouswololo/how-to-server-side-render-react-hydrate-it-on-the-client-and-combine-client-and-server-routes-1a3p
One possible solution here is to make the HTML template an empty template with a generate:after
hook where we do all the rendering process.
Don't worry about the architecture of the React component. We'll dedicate time converting it to a UI library in the next cycles.
Let's forget about the theme
feature of the component for now. It will only have a single "theme" and it's the one matching the styles of the HTML template. We'll add support for themes on the future UI library instead.
Those that may be present on the HTML template but not on the React component.
The HTML template supports some parameters like singleFile
, baseHref
, version
, sidebarOrganization
, and others. We should make sure they still work.
The idea is to start moving towards a single source of truth for our UI components. This is just the first step before we start working on the UI library which will offer many components instead of just a single big one.
In the near future, we'll also have our own design system for those who want to create custom AsyncAPI components that still match our look & feel.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.