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

Integration with Swagger 2 / Open API #136

Closed
BenDave opened this issue Nov 7, 2016 · 20 comments
Closed

Integration with Swagger 2 / Open API #136

BenDave opened this issue Nov 7, 2016 · 20 comments

Comments

@BenDave
Copy link

BenDave commented Nov 7, 2016

We are considering using Swagger to generate API documentation and spring-cloud-contract for contract driven development.

There is an obvious similarity / overlap between spring-cloud-contract and Swagger 2 in that they both use a DSL to describe some element of an API. spring-cloud-contract focuses on scenarios that an API must fulfill while Swagger generates a technical description of the data model + response codes (as described by @marcingrzejszczak in #68 (comment))

The current flow to use spring-cloud-contract and Swagger is at a high level:

  1. Define the API for swagger with the Open API DSL
  2. Generate the API technical documentation with swagger
  3. Define the API scenarios for spring-cloud-contract with the spring-cloud-contract DSL
  4. Generate the tests / stubs with spring-cloud-contract

The 2 main problems are:

  1. No validation of spring-cloud-contract definitions versus the Swagger API definitions. The spring-cloud-contract and Swagger API definitions are independent. It is possible to create spring-cloud-contract based contracts which inadvertently break a definition that was generated for Swagger.
  2. Duplication of API definitions. A given API needs to be manually specified with two different DSLs, which overlap. This is tedious (and error prone as stated above)

It seems that spring-cloud-contract (or another spring project) is bound to extend its capability to encompass the full technical description and documentation of APIs through its DSL, this feeling is reinforced by enhancement request #21 which requires spring-cloud-contract to generate the controller based on the DSL. If this were the case then spring-cloud-contract would need to more fully define the API (e.g. fields, verbs, possibly return codes etc)

We'd love to hear about the short / long term strategy of spring-cloud-contract (or other upcoming spring projects) with respect to full API technical definition and documentation as currently implemented by Swagger 2:

  • Validation of the spring-cloud-contract / OpenAPI DSLs. Is there a plan to somehow integrate spring-cloud-contract with Swagger 2 or the OpenAPI DSL that Swagger 2 uses to perform validation of the DSLs ?
  • Is there a plan for spring-cloud-contract to extend its functionality and fully describe an API and its documentation (Add feature to generate Spring controllers based on contract DSL #21 ) seems to be a step towards this)

Thanks ...

@marcingrzejszczak
Copy link
Contributor

Hello! Thanks for the introduction :)

let me focus on two last questions:

Validation of the spring-cloud-contract / OpenAPI DSLs. Is there a plan to somehow integrate spring-cloud-contract with Swagger 2 or the OpenAPI DSL that Swagger 2 uses to perform validation of the DSLs ?

We will be treating Swagger and its OpenAPI DSL in the same way as we will treat RAML and Pact. You'll be able to use their DSL to define scenarios. We will then convert their DSL into our DSL and then continue with test generation etc.

Is there a plan for spring-cloud-contract to extend its functionality and fully describe an API and its documentation (#21 ) seems to be a step towards this)

#21 would be done only to create a stub of a controller. Contracts are not schemas and never will be. We do not want to describe all possible fields inside a controller. In other words we don't want to replicate what Swagger does. We want to go with Postel's law and we completely don't care how the full model looks like (i.e. what fields it contains).

@BenDave
Copy link
Author

BenDave commented Nov 8, 2016

Thanks for the response @marcingrzejszczak, it makes sense :-)

I guess that OpenAPI will let us use vendor specific DSL which Swagger will ignore but which will be used by spring-cloud-contract to generate the various contract artifacts ?

@marcingrzejszczak
Copy link
Contributor

Yes - instead of using the Groovy DSL you'll be able to use OpenAPI DSL. We will then convert it into our Groovy DSL and then convert those into tests and stubs.

Obviously we're counting on help with implementing this feature cause currently we have bigger priorities. Of course I can help with some guidance. So @BenDave - interested in filing a PR ? :D

@BenDave
Copy link
Author

BenDave commented Nov 8, 2016

That is very tempting :-)

We may have some folks interested in spending a bit of time on this, I will have to get back to you on that ..

@marcingrzejszczak
Copy link
Contributor

Ok! Feel free to ask!

@markward-schubert
Copy link

Hi!

Is there any update on this?
I came across this thread, as we are currently into the same situation, planning to use OpenAPI and Spring Contract Verifier together.

May be we would be willing to contribute some time to this feature, though I confess, that after a glance in the github repositry I could not really understand how the code-generation stuff works.

This leads me to another question:

I stumbled across https://bitbucket.org/atlassian/swagger-request-validator, which has a submodule for RestAssured in the form of a filter. But unfortunately it looks like filters are not supported by RestAssuredMockMVC? I thought it might be a cheaper angle of attack to maybe extend the way the testcases are generated in order to offer an optional OpenAPI validation in the generated testst. Sure, this would only remove one "redundancy", the one of writing separate tests for the OpenAPI and the Contract but leaves the "redundancy" of writing two kinds of "specifications" the OpenAPI one and the Contract Verifier DSL specs.

@marcingrzejszczak
Copy link
Contributor

Nope - no progress for now. You can check out this example - https://github.com/spring-cloud/spring-cloud-contract/blob/master/spring-cloud-contract-tools/spring-cloud-contract-spec-pact/src/main/groovy/org/springframework/cloud/contract/verifier/spec/pact/PactContractConverter.groovy It's pretty straightforward. You have to provide a conversion to a Collection and from it.

May be we would be willing to contribute some time to this feature, though I confess, that after a glance in the github repositry I could not really understand how the code-generation stuff works.

If you just do the conversion to/from Contract you don't have to touch the code generation. If you want to have your custom code generation then you could base your work on how org.springframework.cloud.contract.verifier.builder.JavaTestGenerator is working. Then you could just provide your own implementation and register it in spring.factories under org.springframework.cloud.contract.verifier.builder.SingleTestGenerator entry

Filters are not handled by MockMVC but you can use the EXPLICIT mode in SC-Contract to start RestAssured and send a real request.

... testcases are generated in order to offer an optional OpenAPI validation in the generated testst ...

What do you mean exactly by this? What is this additional optional OpenAPI validation?

@markward-schubert
Copy link

My assumption was that the OpenAPI validation as done by swagger-request-validator via a RestAssured filter would be something, that not all users of Spring Contract Validator would want to use. So I thought one would provide this feature optional. Like "test, what was specified in the DSL" and (optionally) "check the request/response against an OpenAPI specification".
These thoughts were based on the assumption, that the verification would have to be initialized in the generated code part and not the custom baseClass. If it can be done in the baseClass, of course it would be totally up to the user of the framework.

I did not dig into the EXPLICIT mode yet, as maybe I misunderstood its intention. I will check.
Thanks for the support!

@marcingrzejszczak
Copy link
Contributor

Hmm I don't think it's generic enough to consider putting in core :/ Here you have an example of working with context paths that require the EXPLICIT mode - https://cloud.spring.io/spring-cloud-contract/spring-cloud-contract.html#_working_with_context_paths

@marcingrzejszczak
Copy link
Contributor

@BenDave @markward-schubert @fitzoh I was thinking about this issue when working on this one #227 and I have one gigantic problem with this compatibility. Swagger / Open API are schema based. They define a schema and possible responses for different response codes. Spring Cloud Contract is scenario based. For a single request you've got a single response. It's actually impossible to make those two work (you'd have to start keeping multiple Open API schema files for different status codes which obviously makes no sense).

I'm on the verge of closing that PR and both issues for RAML and Open API due to incompatibilities. What do you think about this?

@fitzoh
Copy link
Contributor

fitzoh commented Feb 22, 2017

Yeah, I was always a little bit curious about how those implementations were going to work out, there's a pretty big mismatch in how SCC and swagger/RAML work.

Regarding your comments on #227 about not including it due to the limitations, maybe it makes sense to release it separately as a community-ish project? You've got the plug-in interface for converting stuff now, maybe it makes sense to have some external converters that aren't going to have first class support?

@marcingrzejszczak
Copy link
Contributor

Following the discussion here #227 it turns out that schema based solutions are not really suitable as input for Spring Cloud Contract. @fitzoh the RAML thing will be moved to Spring Cloud Incubator.

@BenDave
Copy link
Author

BenDave commented Feb 24, 2017

Yes, that decision makes sense - thanks for looking into this ....

@fitzoh
Copy link
Contributor

fitzoh commented Mar 27, 2017

@marcingrzejszczak This might be worth checking out if this gets reopened at some point:
https://bitbucket.org/atlassian/swagger-mock-validator

And some info on how it works with Pact:
https://docs.pact.io/faq/convinceme.html#but-i-use-swaggeropenapi
pact-foundation/pact-specification#28

cc @mefellows

@mefellows
Copy link

Good idea @fitzoh.

Broadly speaking, the two technologies offer up different things; one is really useful for documenting APIs, in particular providing a strong definition where the consumers are not well known, the other is well suited to integration tests and providing confidence for known consumers.

It seems there is a common but happy middle ground that people are constantly wanting - the ability to do both.

As a suggestion, I'd see how the mock validator goes and if it turns out people like it, one option could be to create a spring-cloud-contracts integration that does something similar, or even implement something similar into the core library.

@fitzoh
Copy link
Contributor

fitzoh commented Mar 27, 2017

Wanted to include a link to the other half of that project:
https://bitbucket.org/atlassian/swagger-request-validator

They have wiremock and restassured validators as well.

@marcingrzejszczak
Copy link
Contributor

Thanks for the feedback! Looks interesting. However I think that the best place to make that integration would be on the atlassian side. Also it's a validator that the Swagger special tells the truth. This issue was about making the Swagger spec input for sc contract. So it's a little bit different thing. WDYT?

@leoncio44
Copy link

Hi, it might be a silly idea, but could you use the default values of the parameters for the input mock and the response examples for the validation of responses? In this way the swagger template would also serve as a data scenario.

@marcingrzejszczak
Copy link
Contributor

There are community extensions to Spring Cloud Contract that support Swagger like https://github.com/SvenBayer/spring-cloud-contract-swagger and from what I know more are to come :)

@anatoliy-balakirev
Copy link
Contributor

There is also project to kind of merge openapi with spring cloud contracts: https://github.com/springframeworkguru/spring-cloud-contract-oa3#spring-cloud-contract-open-api-30-contract-converter

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

No branches or pull requests

7 participants