GithubHelp home page GithubHelp logo

asyncapi-pitches's People

Contributors

fmvilas avatar

Watchers

 avatar  avatar

asyncapi-pitches's Issues

Intent-driven API design

On This Page

Summary

Problem Overview

Our current parser is tightly coupled to the AsyncAPI document structure.

Solution Overview

Create a new parser API that represents intents instead of the structure of the document.

Positive Side-Effects

  1. When tooling authors have to start supporting future versions of AsyncAPI, they will not have to change their code (unless it's for adding new features that didn't exist before).

Problem Details

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.

Solution guidelines

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.

Boundaries

Don’t release v2 of the parser during the cycle

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.

Please don't consider migrating the Generator templates part of this bet

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.

Watch out for documentation

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.)

Watch out for rabbit holes when listing all the possible intents

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.

Long-Term Vision

OpenAPI 3.0.0 and the adoption problem

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.

Unify HTML template and React component

On This Page

Summary

Problem Overview

We're currently maintaining two HTML documentation views: the HTML template and the React component.

Solution Overview

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.

Positive Side-Effects

  1. Less code to maintain.
  2. Studio is using React so we should be able to render the docs on the client side. That will allow us to get rid of the expensive servers we have for the Playground right now and host it for free on Netlify or similar.

Solution guidelines

While this task may sound easy, there are a bunch of small features/details that are not present in the React component:

  1. It doesn't offer a sidebar navigation.
  2. It's using tables to show information. We already saw in the initial versions of the HTML template that it doesn't scale well as usually most of the fields appear empty.
  3. It has a section of messages and schemas but it only shows the ones under components.
  4. It's using the term "topics" instead of "channels".
  5. It's not using Tailwind.
  6. It's not working with AsyncAPI 2.0.0 (or I can't make it work)
  7. It's merging objects when it finds allOf, which is an incorrect behavior.
  8. It's not handling 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.

Boundaries

Don’t go too far refactoring the React component

Don't worry about the architecture of the React component. We'll dedicate time converting it to a UI library in the next cycles.

Don't support theming

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.

Watch out for those little details

Those that may be present on the HTML template but not on the React component.

Watch out for template parameters

The HTML template supports some parameters like singleFile, baseHref, version, sidebarOrganization, and others. We should make sure they still work.

Long-Term Vision

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.