Add advanced request matching option to WebValve.register
Problem
Currently, WebValve allows mocking of services based on URL matching. However, some APIs use a single URL for multiple endpoints, distinguishing between them using parameters in the request body (e.g., a methodName parameter for some kind of RPC). In these cases, users may want to mock only a subset of the API calls, which is not possible with the current implementation.
Solution
This PR introduces a new request_matcher option for WebValve.register. This option allows users to specify additional request matching criteria, including body content, headers, and query parameters. This enhancement leverages WebMock's request matching capabilities, giving users more fine-grained control over which requests are mocked.
Example Usage
WebValve.register "FakeBank", request_matcher: {
body: WebMock::Matchers::HashIncludingMatcher.new(action: 'limit_order')
}
In this example, only requests to the FakeBank service with a body containing action: 'limit_order' will be mocked. This allows users to selectively mock specific API calls even when they share the same base URL.
Backwards Compatibility
This change is fully backwards compatible. Existing usage of WebValve.register without the request_matcher option will continue to work as before.
We encountered this type of API in our work, which prompted this solution. However, I'm unsure if this is the most suitable approach for the gem's core functionality. Maybe it's too specific to our use case, and it's better to keep this as a private fork only for our project. I'm open to suggestions and feedback, thanks in advance.
hi! thanks for opening this PR. i'm a bit tied up at the moment but will take a closer look at this soon. appreciate your patience.
Find some problems with current approach and need time to investigate it, convert PR to draft for now
hi. thanks @tmnsun.
i've started looking at this and i'm curious to learn what makes this approach more appealing than doing this delegation to the proper fake behavior from within the WebValve::FakeService? That class is basically just a Sinatra app so it has all the power you're looking for here, just another layer removed from the configuration of webvalve.
Hi @samandmoore
Our problem is that we don't fake whole service at once, we need separately fake different parts of it.
Like our vendor don't give us sandbox environment for one particular endpoint and we want to fake it within dev/staging environments, but that one endpoint share same URL as others and use methodName POST parameter. So only to fake this one we need request matcher
Like our vendor don't give us sandbox environment for one particular endpoint and we want to fake it within dev/staging environments, but that one endpoint share same URL as others and use
methodNamePOST parameter. So only to fake this one we need request matcher
oh interesting. so you also need requests that don't match your matcher to actually go through and not be routed to any fake at all?
oh interesting. so you also need requests that don't match your matcher to actually go through and not be routed to any fake at all?
Yes, thats the main reason