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

Added Swagger generation #569

Merged
merged 10 commits into from
Dec 11, 2017
Merged

Conversation

elasti-ron
Copy link
Contributor

@elasti-ron elasti-ron commented Nov 7, 2017

Hi,

I've added the capability to auto-generate static Swagger definition files from the Apipie DSL.

The resulting Swagger (OpenAPI 2.0) compliant JSON file can then be used to auto-generate REST clients, imported into tools like Postman, and so forth.

Swagger generation is implemented by crawling through Apipie's resource_descriptions construct.

The DSL is slightly enhanced to allow indication of default values of optional parameters.

There are a few configuration options that can be used to change the overall structure of the generated swagger file, in order to support both in:formData and in:body REST request styles.

Looking forward to hear your thoughts.

@@ -0,0 +1,583 @@
module Apipie
module Validator
class EnumValidator < BaseValidator
Copy link
Member

Choose a reason for hiding this comment

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

Why not putting it directly to the validator definition?

end


def save_and_compare
Copy link
Member

Choose a reason for hiding this comment

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

This method is not being called from any place? Should it be exposed from the rake?

# note that at the moment, this only takes operation ids into account, and ignores parameter
# definitions, so it's only partially useful.
def include_op_id_in_master_identifier(op_id)
@master_id = Zlib::crc32("#{@master_id} #{op_id}")
Copy link
Member

Choose a reason for hiding this comment

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

we should probably require zlib somewhere: it's probably loaded by rails somewhere, but just to be on safe side

# print "??? RESEARCH: [#{ruby_name_for_method(@current_method)}] -- #{msg}\n"
end

def dump_param_desc(param_desc)
Copy link
Member

Choose a reason for hiding this comment

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

Unused method?

@iNecas
Copy link
Member

iNecas commented Nov 8, 2017

There are some unused methods and commented code, that should be cleaned first. I have not tested this yet, but my view on this is we could get this in pretty soon, as it has not influence on other features, and can be pretty useful for many folks.

@iNecas
Copy link
Member

iNecas commented Nov 8, 2017

I wonder if we could have a test on checking that the swagger output valid, in the tests.

@iNecas
Copy link
Member

iNecas commented Nov 8, 2017

Another question: would it make sense to expose this via an /apidoc endpoint, similarly as we have with apidoc.json?

@elasti-ron
Copy link
Contributor Author

Thanks @iNecas - good points. I'll push a cleaned-up version early next week.

Re exposing via /apidoc: yes, would be useful. Would probably make sense to auto-fill the swagger host field with the hostname/port from the request object. I'll look into this.

Re testing the validity of the swagger output: would be great to add. A possible approach might be to validate against the Swagger schema (perhaps by using the json-shema gem?) on the output. What do you think?

@iNecas
Copy link
Member

iNecas commented Nov 9, 2017

Agreed with all you said :)

* moved EnumValidator#values to validator.rb
* replaced 'save_and_compare' method with new rake task ("apipie:did_swagger_change") and optional 'x-computed-id' info field in output swagger
* added "require 'zlib'" (if configured to generate x-computed-id field)
* removed leftover routines (SwaggerGenerator#investigate, SwaggerGenerator#dump_param_desc)
* added warning_inferring_boolean (when inferring that a [true,false] enum param is really a boolean)
* documented the 'host' configuration param in the README, and made it possible not to include this field in the output
@elasti-ron
Copy link
Contributor Author

Pushed a cleaned-up version addressing the code issues you highlighted.

Will keep you posted on progress re the /apidoc endpoint and the swagger schema validation.

@elasti-ron
Copy link
Contributor Author

Hi @iNecas - it turns out that rendering at runtime from /apidoc is not as simple as I had hoped. It will take me some time before I'm able to look into this further, and I'll only be able to continue working on this (and on the swagger schema validation) next week.

If you feel comfortable with what I've posted so far as a first version, it might be best to merge that into the master branch and not wait for the additional functionality. This will reduce the risk of incompatibilities creeping into the code.

@iNecas
Copy link
Member

iNecas commented Nov 14, 2017

I'm ok with waiting for the /apidoc endpoint, but I wukd lje to have the schema validator test before merging this to keep it working with the further updates

@elasti-ron
Copy link
Contributor Author

The schema validation was surprisingly easy to add. Pushed a version that includes it.

@elasti-ron
Copy link
Contributor Author

ping

@elasti-ron
Copy link
Contributor Author

Hi @iNecas - runtime swagger generation is now supported (with some limitations - see the README).


@language = get_language

Apipie.load_documentation if Apipie.configuration.reload_controllers? || (Rails.version.to_i >= 4.0 && !Rails.application.config.eager_load)
Copy link
Member

Choose a reason for hiding this comment

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

There is quite a lot of code duplicated from the index method. Could you look into how to DRY this a bit?

Otherwise, the implementation looks good and I think we are close to merging this

@swagger_content_type_input = :form_data # this can be :json or :form_data
@swagger_json_input_uses_refs = false
@swagger_include_warning_tags = false
@swagger_suppress_warnings = false #[105,100,102]
Copy link
Member

Choose a reason for hiding this comment

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

What does #[105,100,102] mean?

Copy link
Member

Choose a reason for hiding this comment

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

Nm: I looked at the readme and here we go :)

@iNecas
Copy link
Member

iNecas commented Dec 11, 2017

Thanks @elasti-ron, I don't see any other reason why holding this in a PR any longer. Thanks for hard work and this one. I'm sure it will be useful for others as well

@iNecas iNecas merged commit 75a16bd into Apipie:master Dec 11, 2017
@elasti-ron elasti-ron deleted the swagger_generation branch December 18, 2017 14:04
@elasti-ron
Copy link
Contributor Author

Thanks @iNecas - it was good to collaborate with you on this.

As a next step, I'd like to add support for describing response structures, as it would make the output much more useful.

I've written a proposal to describe my suggested approach, and I would highly appreciate your feedback on it.

@iNecas
Copy link
Member

iNecas commented Jan 2, 2018

Thanks for moving apipie forward. I would have few comments to the proposal: would you mind opening the proposal as a PR, with the markdown document in it. The would for the PR would not be to merge that, but to have a meaningful discussion over the diff itself.

In general, I like the idea of combining the concepts we already have in the apipie. Although, I would suggest introducing additional keyword (something like property) to the dsl: when defining response only keys, I'm not sure it makes sense to talk about parameter in that regard. It would be more like an alias.

I will have more comments, but I would like to leave that for a new PR to continue with the discussion.

@iNecas
Copy link
Member

iNecas commented Jan 2, 2018

Also, make sure to advertise this in #273, as there are other folks interested into this functionality, that could have a valuable input to the progress of this.

@elasti-ron
Copy link
Contributor Author

Done. #588.

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

Successfully merging this pull request may close these issues.

2 participants