Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: add /generator path #7

Merged
merged 26 commits into from
Dec 14, 2021

Conversation

magicmatatjahu
Copy link
Member

@magicmatatjahu magicmatatjahu commented Nov 30, 2021

Description

Add /generator path:

  • in first iteration generate only two official templates, html and markdown
  • add middleware for validation template parameters

Initialize /src structure:

  • separate logic: controllers (logic for route and their initialization), services (business logic and helpers)
  • add global middleware to catch all ProblemException error
  • add global middleware to validate AsyncAPI document being sent
  • add global middleware to validate request body based on operation's schema from OpenAPI Document
  • add unit tests

OpenAPI document:

  • change name of allowed templates, before html and markdown, now @asyncapi/html-template and @asyncapi/markdown-template
  • add required fields to the Problem schema

Some insights:

I think that we should go with names of paths with verbs like in our CLI, so /generator should be /generate, in future /validate, /convert, /bundle etc. I know that we decided go with REST patterns, but it doesn't work, really, I always wrote (in tests and source code) /generate path rather than /generator so it's more natural.

cc: @smoya @jonaslagoni @fmvilas @derberg
If you want share your opinions @BOLT04 I would be grateful, but if you don't have time, it's okay :)

@magicmatatjahu magicmatatjahu added the enhancement New feature or request label Nov 30, 2021
@magicmatatjahu magicmatatjahu marked this pull request as ready for review December 3, 2021 13:33
Copy link
Member

@jonaslagoni jonaslagoni left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few comments 🙂 Looking good 👍

package.json Outdated Show resolved Hide resolved
src/configs/production.json Outdated Show resolved Hide resolved
src/services/archiver.service.ts Show resolved Hide resolved
src/services/generator.service.ts Show resolved Hide resolved
src/utils/logger.ts Outdated Show resolved Hide resolved
src/utils/temp-dir.ts Outdated Show resolved Hide resolved
jonaslagoni
jonaslagoni previously approved these changes Dec 3, 2021
Copy link
Member

@jonaslagoni jonaslagoni left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

@fmvilas
Copy link
Member

fmvilas commented Dec 7, 2021

Yeah, I'd not go with REST design for this API. Pure RPC seems a better fit IMHO. All methods will be POST and paths will always be verbs. The rest of the info can be provided in the request payload. Like you said, @magicmatatjahu, just like a CLI.

Copy link
Member

@fmvilas fmvilas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd just change the path to /generate. Other than that, looks good to me.

headers: {
Cookie: req.header('Cookie'),
},
withCredentials: true,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How this is gonna work? What are the credentials? Are they gonna be based on a cookie? I'm confused.

Copy link
Member Author

@magicmatatjahu magicmatatjahu Dec 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's used for parser options and it's exactly options for json-schema-ref-parser. More info here :) https://github.com/APIDevTools/json-schema-ref-parser/blob/main/docs/options.md#resolve-options In this same way we do in old playground :)

CODEOWNERS Outdated Show resolved Hide resolved
package.json Show resolved Hide resolved
req.parsedDocument,
template,
parameters,
tmpDir,
Copy link
Member

@smoya smoya Dec 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still think we should move into generating in memory, writing directly to the zip stream by using (If I'm correct) append archiver method: https://www.archiverjs.com/docs/archiver#append.

The whole process will be generated on the fly, way faster, and theoretically, since you piped the stream to the response object, data should be flushed on each write, isn't? Meaning you don't hold everything in memory but just a small buffer since everything is drained though the response (sent back to the client).

Copy link
Member Author

@magicmatatjahu magicmatatjahu Dec 10, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@smoya Maybe I'm not understanding it correctly, but how to do that if generator uses under the hood filesystem api to "render" templates? For that I passed directory destination for output.

@smoya
Copy link
Member

smoya commented Dec 9, 2021

I just want to drop a comment regarding the whole design pattern used on this app. We are currently following some sort of MVC pattern, which it is enough for simple applications IMHO (like this one today).

However, I can detect and I would say even foresee that the logic on this API will be very similar, in part, to what the CLI does nowadays.
What about moving into a more Hexagonal Architecture pattern, where we can reuse most of the logic of both apps but the only (or mostly) thing that changes are ports and adapters?
Maybe worth discussing this in a new issue or discussion.

1 similar comment
@smoya
Copy link
Member

smoya commented Dec 9, 2021

I just want to drop a comment regarding the whole design pattern used on this app. We are currently following some sort of MVC pattern, which it is enough for simple applications IMHO (like this one today).

However, I can detect and I would say even foresee that the logic on this API will be very similar, in part, to what the CLI does nowadays.
What about moving into a more Hexagonal Architecture pattern, where we can reuse most of the logic of both apps but the only (or mostly) thing that changes are ports and adapters?
Maybe worth discussing this in a new issue or discussion.

@BOLT04
Copy link
Member

BOLT04 commented Dec 9, 2021

I just want to drop a comment regarding the whole design pattern used on this app. We are currently following some sort of MVC pattern, which it is enough for simple applications IMHO (like this one today).

However, I can detect and I would say even foresee that the logic on this API will be very similar, in part, to what the CLI does nowadays. What about moving into a more Hexagonal Architecture pattern, where we can reuse most of the logic of both apps but the only (or mostly) thing that changes are ports and adapters? Maybe worth discussing this in a new issue or discussion.

@smoya I totally agree on moving to another architecture if you foresee most logic will be reusable on this API and the CLI 👍.
I'm more familiar with Clean Architecture which I believe is inspired by the hexagonal architecture and others.
Both have the same ideas IMO, we would have a different TS module with the core of the "system". This core module will have that reusable logic you mentioned, and is framework independent so that we can use it in this HTTP API with Express.js or with oclif in the CLI tool. Not just these two but other apps that use different "ports" that we can adapt to the core's interface 🙂.

Do you think it's worth chasing a move towards this architecture now, or keep it simple until we find the need to change the architecture (I'm kinda debating whether to follow the KISS principle or do more upfront design 😅)?

Could you share briefly what sort of areas you see being reused? I'm asking because I had a look at this PR and the CLI repo, but couldn't find the type of logic that this API would use (I mostly looked at commands and models).

@magicmatatjahu
Copy link
Member Author

@smoya @BOLT04 Thanks for review and for feedback!

Honestly, about hexagonal architecture, I don't think so that it will be good idea. CLI (as @BOLT04 noted) has models and command, server-api will have controllers/routes (and some services). Even if we wanna create reusable parts (like services) we should see that for CLI/Server-API given service can be significantly different for two given environments. For example the generator - on the server side we have to generate in temporary folders and send the zip, in the CLI we generate in the folder specified by the user. I can say that currently we are using quasi-hexagonal pattern due to the fact that every tool in our organization is separate library and can be easily integrated into every environment. Why make life difficult for yourself, make wrappers/adapters in one, shared place and then again in another place, whether it is a server or CLI? 🤷🏼

@smoya
Copy link
Member

smoya commented Dec 10, 2021

@smoya @BOLT04 Thanks for review and for feedback!

Honestly, about hexagonal architecture, I don't think so that it will be good idea. CLI (as @BOLT04 noted) has models and command, server-api will have controllers/routes (and some services). Even if we wanna create reusable parts (like services) we should see that for CLI/Server-API given service can be significantly different for two given environments. For example the generator - on the server side we have to generate in temporary folders and send the zip, in the CLI we generate in the folder specified by the user. I can say that currently we are using quasi-hexagonal pattern due to the fact that every tool in our organization is separate library and can be easily integrated into every environment. Why make life difficult for yourself, make wrappers/adapters in one, shared place and then again in another place, whether it is a server or CLI? 🤷🏼

Maybe its time to change the generator :).

Anyway, I will move this into separate issues so we are not completely blocking this pr.

Copy link
Member

@smoya smoya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a couple of concerns I will like to resolve asap. However, im gonna approve this PR so we can discuss those deeply and move forward without blocking.

🚀 Nice job @magicmatatjahu !!!💯

Copy link
Member

@BOLT04 BOLT04 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

@BOLT04
Copy link
Member

BOLT04 commented Dec 11, 2021

Anyway, I will move this into separate issues so we are not completely blocking this pr.

@smoya could you add the link for the issue afterward here? I'd like to follow that discussion 🙂

@sonarcloud
Copy link

sonarcloud bot commented Dec 14, 2021

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 15 Code Smells

No Coverage information No Coverage information
0.8% 0.8% Duplication

@magicmatatjahu
Copy link
Member Author

I see some code smells from SonarCloud. I will merge that PR with chore: to not trigger release, because we don't have yet integrated needed packages to release automation, I will also fix that issues in the next PR and we can release 0.1.0 :)

@magicmatatjahu magicmatatjahu changed the title feat: add /generator path chore: add /generator path Dec 14, 2021
@magicmatatjahu magicmatatjahu merged commit 8d8506b into asyncapi:master Dec 14, 2021
@magicmatatjahu magicmatatjahu deleted the generate-path branch December 14, 2021 10:19
@smoya
Copy link
Member

smoya commented Dec 29, 2021

@smoya @BOLT04 Thanks for review and for feedback!

Honestly, about hexagonal architecture, I don't think so that it will be good idea. CLI (as @BOLT04 noted) has models and command, server-api will have controllers/routes (and some services). Even if we wanna create reusable parts (like services) we should see that for CLI/Server-API given service can be significantly different for two given environments. For example the generator - on the server side we have to generate in temporary folders and send the zip, in the CLI we generate in the folder specified by the user. I can say that currently we are using quasi-hexagonal pattern due to the fact that every tool in our organization is separate library and can be easily integrated into every environment. Why make life difficult for yourself, make wrappers/adapters in one, shared place and then again in another place, whether it is a server or CLI? 🤷🏼

Maybe its time to change the generator :).

Anyway, I will move this into separate issues so we are not completely blocking this pr.

@magicmatatjahu @BOLT04 I created a discussion about this topic with a more expanded context. You might want to look at it asyncapi/community#212

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants