pact-foundation / pact-mock_service

Provides a mock service for use with Pact
https://pact.io
MIT License
72 stars 68 forks source link

Feature Request - support dynamic responses based on ID in request #110

Open YOU54F opened 5 years ago

YOU54F commented 5 years ago

Feature Request - support dynamic responses based on ID in request

Why? - one of the key features of pact-stub-service, is its ability to be used in integration / e2e tests. Allowing dynamic responses based on a user provided ID in the request body would allow it to stub real world scenarios in which a client requests an operation on a specific resource and the provider returns a reference to that resource in the request body. A consumer would validate this resource reference to ensure that any operations based on the response is for the correct resource.

This feature request would bring pact stub service closer to other API mocking tools such as wiremock (see http://wiremock.org/docs/response-templating/).

Current state of play :-

I have a pact that will accept http://localhost:8084/request/path/1

and will return

{
    "id": "1",
    "status": "LOOSE_MATCH"
}

It is setup with a term matcher on the request path

            path: term({
              generate: requestPath,
              matcher: "/request/path/(?![2]$)\\d+"
            })

so that it will match anything that isn’t http://localhost:8084/request/path/2

I want to set it up so that when I perform the request http://localhost:8084/request/path/123, the response body will return the ID in the url that was matched

{
    "id": "123",
    "status": "LOOSE_MATCH"
}

My pact test is here https://github.com/YOU54F/jest-pact-typescript/blob/requestPathExample/src/pact/client/requestPathMatching.pacttest.ts

and my generated pact is here https://github.com/YOU54F/jest-pact-typescript/blob/requestPathExample/docker/pact-stub-service/pacts/test-consumer-request-path-provider.json

Full example in a PR :- https://github.com/YOU54F/jest-pact-typescript/pull/101

Instructions to run example

1. `git clone git@github.com:YOU54F/jest-pact-typescript.git`
2. `git checkout requestPathExample`
3. `yarn install`
4. `yarn run pact-test`
5. `cd docker/pact-stub-service`
6. `make copy-pacts`
7. `cd ../docker`
8. `docker-compose up`

My initial thoughts

I wonder if, similar to the verifier where you can override the response body, if we do a similar thing within the stub service, without having to mess with the contracts themselves.

Response from Matt -

That’s probably the approach that would be taken, or at the very least, it would be authored separately to the test itself and appended to the contract. Could even be a separate file that contained predicates/stub logic

Comments initially raised in slack https://pact-foundation.slack.com/archives/C9VBGLUM9/p1559955411019400

YOU54F commented 5 years ago

This is the feature request in the verifier that introduced custom middleware.

https://github.com/pact-foundation/pact-provider-verifier/pull/27/files

Would we be looking at implementing something like this?

bethesque commented 5 years ago

I've been musing about how to make the generated contract more useful as a stub for quite a long time, and one of the reasons I haven't gotten around to it is that it always required putting extra information into the unit test interaction that wasn't actually going to be used by the unit test. I couldn't work out how to do it elegantly!

Custom middleware would be one way to achieve this without messing with the contract. I like where that is going. Are you interested in doing a small spike @YOU54F?

YOU54F commented 5 years ago

Yeah having a think about it, will see what I can rustle up, as this along with the query param matching in the mock service are the two things we are missing in the pact stub service, and it would save me a load of work and headache having to move everything over to wiremock.

My devs are giving me grief about it, and want to switch to wiremock, and although I can use the pact mock verifier to ensure that the wiremock service they create, stay in sync with the pact, they think it is additional maintenance overhead. I disagree, as I believe if they are creating wiremock as a separate thing to the pacts, we would want to ensure that they are actually representative of the providers they are mocking.

praveen-em commented 1 year ago

Hey @YOU54F @bethesque , just curious if there was any further movement on this topic?

YOU54F commented 9 months ago

Hey Pravs, I never picked this up again, also now that time has passed this this raised I haven't checked what the two Rust projects are like with regards as to whether they include this ability.

I'm sure I'll scratch that itch sometime soon ( I would now it I was rammoed)