asyncapi / html-template

HTML template for AsyncAPI Generator. Use it to generate a static docs. It is using AsyncAPI React component under the hood.
63 stars 56 forks source link

Undefined message error when spliting the subscriber/pubsli into separated file. #110

Closed sofialunkes closed 3 years ago

sofialunkes commented 3 years ago

I'm working on documenting events at my job, and found this amazing tool.

But I'm facing a problem. We have a lot of subscribers and publishers (runs in microservices architecture) and we need to split them according to the event that is being triggered and consumed.

example: microservice: timeline events:

But when i split this events into different files and reference them in another file representing the domain, i run html-template and returns me an error. Here is:

Something went wrong:
Error: Cannot read property 'message' of undefined
    at parse (/usr/local/lib/node_modules/@asyncapi/generator/node_modules/@asyncapi/parser/lib/parser.js:106:11)
    at async Generator.generateFromString (/usr/local/lib/node_modules/@asyncapi/generator/lib/generator.js:234:21)
    at async /usr/local/lib/node_modules/@asyncapi/generator/cli.js:123:9

Here is an example repository: https://github.com/sofialunkes/asyncapi-spec-events This repository represent exactly how we are separating domains

We use the same strategy for openAPI and works fine. Maybe it should work the same way for AsyncAPI?

Thanks for the support guys, keep this amazing work!

github-actions[bot] commented 3 years ago

Welcome to AsyncAPI. Thanks a lot for reporting your first issue. Keep in mind there are also other channels you can use to interact with AsyncAPI community. For more details check out this issue.

derberg commented 3 years ago

Thanks for the kind words! It always gives power 💪

I looked at your example, you have a few errors there.

This us how AsyncAPI file should look like:

asyncapi: 2.0.0
info:
  title: Dummy Events
  version: 1.0.0
  description: This service is in charge of processing dummy signups
tags:
  - name: user
    description: User-related messages
channels:
  dummy::signups:
    $ref: "dummy/dummy-signup.yml"
components:
  messages:
    mymessage:
      $ref: "dummy/schema.yml#/DummySignup"

Have a look at the components.messages. In spec we explain that messages is a Map of string and message/ref object.

Also the file that holds information about channel operation should look like:

subscribe:
  operationId: transaction::authorization
  description: teste
  message:
    $ref: "schema.yml#/DummySignup"

schema.yml#/components/messages/DummySignup could never work as this is not how the structure of schema.yml looks like.

I hope this makes sense. Let me know if you have more questions. Once we fix this bug you should get proper errors and not such a crappy type error as now, sorry for that.

sofialunkes commented 3 years ago

Hi!

oh I didn't noticed the first problem theschema.yml#/components/messages/DummySignup, thank you for checking this!

But this:

components:
  messages:
    mymessage:
      $ref: "dummy/schema.yml#/DummySignup"

I don't think is right.. If we have different channels, the object will not reference others than the DummySignup.

When i write this way, it works.

asyncapi: 2.0.0
info:
  title: Dummy Events
  version: 1.0.0
  description: This service is in charge of processing dummy signups
tags:
  - name: user
    description: User-related messages
channels:
  dummy::signups:
    subscribe:
      operationId: dummy::signup
      description: Dummy signup
      message:
        $ref: "./dummy/schema.yml#/DummySignup"
components:
  messages:
    $ref: "./dummy/schema.yml"

Note that the components.messages is not referecing an specific object.

The problem is, the channel dummy::signups is not working when i changed it to another file and reference it. This is a problem when i have different events that are emitted in one microservice, this file becomes giant and difficult to read.

I think it could be better managed if we split the events into different files and write those specific descriptions and behaviours into them.

Example:

asyncapi: 2.0.0
info:
  title: Dummy Events
  version: 1.0.0
  description: This service is in charge of processing dummy signups
tags:
  - name: user
    description: User-related messages
channels:
  dummy::signups:
    $ref: "./dummy/dummy-signup.yml"
  dummy::signouts:
    $ref: "./dummy/dummy-signout.yml"
components:
  messages:
    $ref: "./dummy/schema.yml"

And each of the channels, have it's own descriptions, examples, operations, etc..

Does it makes sense to you or I'm dreaming too much? haha Thank you for the attention.

derberg commented 3 years ago

tl;dr your example is a valid example, you just do not have content here https://github.com/sofialunkes/asyncapi-spec-events/blob/master/dummy/dummy-signup.yml

This 👇 works because of the structure you have in schema.yml file, map of string and message object. Also keep in mind that maybe it works, but there is no reference from channel to components section, so it is not clear what those messages are for. Components are for reusability in case you want to reference for channel object

 messages:
    $ref: "./dummy/schema.yml"

But at scale, what is the difference between having all messages under components.messages or under a single file like schema.yml. Not much difference. If you do 👇 then you can have message per file.

components:
  messages:
    myDummyMessage1:
      $ref: "dummy/message1.yml"
    myDummyMessage2:
      $ref: "dummy/message2.yml"

I create a PR to your repo the way it works on my side -> https://github.com/sofialunkes/asyncapi-spec-events/pull/1 good stuff in my proposal is that schema is now really an independent file, which means it can be used not only in documentation but can be easily shared with the application, for validation in runtime for example (one of use cases https://github.com/WaleedAshraf/asyncapi-validator)