-
Notifications
You must be signed in to change notification settings - Fork 6k
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
Customization of folder structure for a template #3515
Comments
I've done some more research. Currently, there are two main generators in the swagger family: node-swagger and this project. Comparison in short: This project is more advanced in the manner that it generates handlers capable of responding mock replies based on the responses declared in the spec, where node-swagger generates only a boilerplate from which the developer has to proceed by himself. So codeGen is more advanced in that it creates a server capable of returning mock replies By supporting folder-structure customization, IMHO - this project could gain an additional edge aside to the mock responses. Thoughts? |
@osher thanks for the feedback on the nodejs-server generator. For nodejs server-side project, is there a recommended folder structure for the project? Technically it's possible to introduce CLI options to customize the folder for different auto-generated JS files but I think it's important to understand if there's any best practices for nodejs folder structure. For auto-generated test cases, we have that for other language generator (but not all), e.g. Ruby, Python, PHP, C#, Java, etc: #2276 and we're looking for contribution to add those for |
Such a typical question for Java folk ;) anyway - Good question, I'm happy you asked. I may not be able to post it today, and this is the end of my week. If not to day - I'll post it on sunday. |
@osher please take your time. We always welcome feedback to make Swagger Codegen better. Your suggested folder structure looks good to me. What I would like to do it to make sure we're following the NodeJS industry standard/style guide, if any, to avoid changing it again in the future. |
First - disclaimer:Any folder-structure would be _opinionated_ - and JS developers are often kinda ...gently put - sensitive to opinionsm. To show you around the versatility in the JS world, I will provide 2 structures bellow, but please hear me here: honest recommendationI recommend to strive to decouple the generator logic from the folder structure My heart tells me that if you can do that - you won't need so many generator classes as you now have in the project, because you will work out of the generic base common to all of them. But that's a side-effect of my proposition, it's not my goal. According to this recommendation - the feature would work best if a source folder structure is cloned, and by recursive iteration - every file in that source structure is bound to it's model and rendered into the relative path in the target. In this I can distinct between 2 types of source template files, according to the model they require and the times they are bound
mm. well. my bad. I missed in my original post a 3rd type.
The user wants e2e tests? great. The template structure will include test files, bound per apiDoc.path. Well. There could be a discussion about case in which same controller handles few paths. sample folder structuresSo now, like I promised - here are two options of folder structures. what is provided by the swagger-nodeThe swagger-node supports 5 templates for 5 competing nodejs frameworks: The command is
However, the boiler-plate there is very simplistic. It does not read a spec-file, and does not use a templating engine to bind it. It's purpose is just to show you an opinionated way (which is already a pitfall in the JS community). Anyway - this structure, contradict the opinions in my school. What I would do if I had the freedom to do itFirst - we use a flat test directory. Any directories in the test folder are reserved to test tools, fixtures and mocks, and paths of test targets are encoded in file-names Having that said - assuming the package is named foo - we end with:
I saw somewhere that you already support a flag to suppress Model generations. |
I also agree that we need to have different folder structure that is more up to date, as a default I would say above will be good starting point I am not sure its important on phaze 1 to enable client to decide on different folder structure other than above Must share with you that this project remind me of Yoman |
I thought of another way to tell what model should be bound with what file. The proposition relays on encoding in the file name all the information about how it should be bound.
file-names should also be bound with placeholders, for {{controller}} and {{definition}} Examples:
Please excuse me - I did not take the time to find the entry names you currently use for {{controller}} and {{definition}} - I really have to call it a day (and a week actually) I'm not quite happy with the part in the proposition that handles partials. I'd be happy to hear your thoughts. Last - I presented my research here in the organization, and showed them the fast responses I got from you. Although the last time I really did Java it was with Java1.2, this organization have a strong Java team, and they are currently considering allocating some dev-time to contribute a PR with this functionality. |
There are definitely many opinions for this. I suggest avoiding making this too smart right now, and target a 3.0 release. As it stands, the technique to change folder structures is embedded in java logic and until we do a major redo on the generation step, let's put this on hold. |
@fehguy: I think I understand. In that storyline of developing a template for ourselves - as a first step, my POC is to create a template that uses modern node-js tools for the existing NodeJS server generator. |
I, for one, would just like to see the mocks separated from the controllers, and have the controllers call the mocks based on an environment variable. Something like (pseudocode): var mock = process.env(‘mock’);
if (mock) {
exports = require(‘./mocks/<thisfilename>’)
} else {
... /* real service here */
} I've poked around a bit at the the languages source code, to figure out how I would generated a mock folder; looks like the override apiFileFolder() determines the (single) output folder for the controller api, used by AbstractJavaJAXRSServerCodegen.java. This is just the start of the rabbit hole, I'm pretty sure. |
Hi folks, First, the original idea was from a (ex) java guy. So the delegation between the controller and service is, shall we say, a little lame. I have recently been building a lot of services and have modified the templates to have the same structure--a controller and a service class--but to user Promises and clearly separate the request/response objects between the controller and service class. So the pattern for a method in the controller might be like this: module.exports.setHeaterState = function setHeaterState (req, res, next) {
var zoneId = req.swagger.params.zoneId.value;
var state = req.swagger.params.state.value;
environment.setHeaterState(zoneId, state)
.then(function (data) {
helpers.json(res, data);
})
.catch(function (err) {
helpers.json(res, err, err.code);
});
}; the The implementation ( exports.setHeaterState = function(zoneId, state) {
return new Promise(function(resolve, reject) {
// business logic here
if(notFound) {
reject({
code: 404, status: 'not found'
});
return;
}
resolve({
code: 200,
message: 'set zone ' + zoneId + ' to ' + state
});
});
} Second, the folder structure currently is a pain. Why? Well, there are no shortages of opinions, but from a tooling person, it's nice to have a clear separation of auto-generated classes (controller classes in this case) and human modified ones (service classes). The goal would be that the controller classes are always overwritten, and having them in a separate folder would be easier for this house keeping. Third, the default routes for, say the docs and the swagger json file, are configurable and pretty much never right with this template set. They should "default to the best practice" and allow for overrides. I personally don't mind the mock code living in the service classes. The reason is, it gives you something to start with when implementing, and you're going to remove it anyway. If the service has a flag to enable/disable mocking, then it may make sense to have something else to intercept the requests, and therefore a mock folder may make sense. |
Since I am writing against legacy code with its own API, I have my service template written to call an adapter; the idea is that both Controller and Service get overwritten, and the Service template checks for its Adapter... if not found, it will return a stub (mock). In the service template, I pushed all the stub data to the bottom of the file and reference each stub by method name (e.g., petGET). I wrote a test template and modified codegen to put those in a separate folder. One thing I didn't like having to do was to modify the NodeJS generator code to add new templates. New template paths, file names, and model type could be read into the generator code via a data structure. It's not that changing/compiling the swagger-codegen code was hard, but all I was doing was adding data inline to methods that could have read that data in from some source. |
@wing328 - I really appreciate the persistence and the seriousness but I had to move on with other solutions, so I'll have to admit I stopped following. |
@osher no problem. Just open a new issue if you need help from us. |
@osher in the end, what solution did you use? I am also researching a way to make a custom project / CRUD template with structure/test/docs included, at the moment this is the best candidate. |
wow. that was a long time ago. But back then I went all in: The generator read your swagger, generated a server with mock responses based on the declared model, a test suite with a suite per endpoint and a case per parameter-permutation, asserted the validity of the returned model, and a client package to consume your service with. All you had to do was provide server implementation, and sometimes add that complicated specific edge test-case. If you're doing micros - then the happy paths of the integration tests put you in 90% coverage without any effort. Anyway, the customers after that were not much into swagger, so I'm quite outdated by now because I was doing other things (diverted a lot towards the ops side, just until this swinging pendulum will take me back). If I had to do it again - I'd still chose node and |
Description
I'm not sure I'm in the right place, please bear with me...
and such.
For example,
to:
I don't find any documentations about it :(
Can anybody point me to the right direction?
Swagger-codegen version
cloned from master + a PR I applied (which was merged to master)
So call it 2.2.1-latest?
Swagger declaration file content or url
This is not a bug the spec file produces.
Command line used for generation
(windows user)
Steps to reproduce
It works, but I want it to work differently.
I want to control the folder-structure.
Related issues
none
Suggest a Fix
Maybe it's a completely new feature request.
Ideally,
As a user - I want to provide a path, and a list of a per-controller files (call it option 1)
or - alternatively - a project dir path, a controller-router dir path (call it option 2)
Then, the expected behavior would be:
every file in the project dir recursively is bound with the model once and rendered to the target folder, preserving relative path it's found in the source dir
if we're doing 1st option - the files listed as per-controller-router files are excluded of the first round, but are bound once per controller-router with a model that features also a reference to the current operation (can be null when binding project files)
if we're doing 2nd option - then, recursively, per controller-router - every file in the controller dir path is bound with the model once and rendered to the target folder, again preserving relative path it's was found in the source dir
(2nd option probably allow more code-reuse with the folder-structure recursion and all...)
I deem this will grant enough control to use codeGen to provide any folder structure.
The text was updated successfully, but these errors were encountered: