pact-foundation / pact-ruby

Enables consumer driven contract testing, providing a mock service and DSL for the consumer project, and interaction playback and verification for the service provider project.
https://pact.io
MIT License
2.16k stars 214 forks source link

Allow parts of request to be changed by provider state #161

Open tucker-m opened 6 years ago

tucker-m commented 6 years ago

Hi Pact,

I have an idea for a new feature, with a working implementation that I'd like your input on. It's something that solves a lot of problems we were running into when trying to use Pact.

In short, it allows you to specify values in the contract that won't be filled in until the provider state set up runs. This is useful for putting things like object IDs in the URL. I've been calling it "provider parameters."

You can specify a parameter like this:

path: Pact.provider_param('/animals/:{animal_id}/profile', {animal_id: '7'}),

And then, in your provider state, set a different animal_id value like this:

persisted_animal = Animal.create!
provider_param :animal_id, persisted_animal.id

So when you run it against the mock service provider, the request will be /animals/7/profile, but when you run the verify step against a real provider, it would use the actual ID of the animal that was created in your provider state.

I've forked this repository at https://github.com/tucker-m/pact-ruby, with a README.md explaining how to use it with some examples. The commit history is a mess right now, but I'd be glad to clean that up if this is something you would be interested in as a pull request.

I've love to hear any feedback you have about this concept and answer any questions about it.

Thanks,

-Tucker

bethesque commented 6 years ago

I believe this feature is part of the v4 spec. Is that right @uglyog?

uglyog commented 6 years ago

I think you are referring to generators from the V3 spec, but they are independent of the provider states. It makes sense that the generators should not be tied to the implementation of the provider state, as that could introduce coupling to setup in the generators behaviour.

But if we have a specific type of generator that is explicit in that it is based on the provider state, that would be really useful.

I have also been thinking of introducing references to the pact files (as in the :{animal_id} above, so you could do thinks like include the values from the request in the response. Location header is an example of where this would be useful), but I'm still undecided if the benefit warrants the increased complexity. Nothing has been added to the V4 spec as yet.

tucker-m commented 6 years ago

Hi @uglyog, thanks for the info. So, is this something that could be added to a future version of Pact? And if so, would it be possible for me to submit this as a pull request, if I made some changes that make it more in line with what you were planning on doing? We'd like to use this for our Pact setup, and it seems like some other Pact users have run into similar needs, like in issues #49 and #84.

rholshausen commented 6 years ago

PR's are always welcome, it's how the open-source world is built.