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

Definitive word on PACT and HATEOAS #102

Open
csydvs opened this issue Jan 12, 2023 · 1 comment
Open

Definitive word on PACT and HATEOAS #102

csydvs opened this issue Jan 12, 2023 · 1 comment

Comments

@csydvs
Copy link

csydvs commented Jan 12, 2023

Just wanted to get the latest definitive word on recommendations for pact in a hypermedia-rich rest api world. For reference, we generally use spring-hateoas, but I think the same sort of question would apply using HAL, Siren, or anything else that implements the HATEOAS standard.

For anyone else asking the same thing, you might have stumbled across this "Traversion support in Pact" issue, but I think we've come a long ways from there. Now, we have this article (implemented in this repository) that talks extensively about validating endpoints that contain HATEOAS information on them, which is great support in this direction.

I think the question that I haven't found a super straightforward answer to is whether it's a bad idea to use provider state injection to set up contracts with APIs that the consumer is never actually aware of themselves. For example, in the example of an orders API, let's say that each order contains a list of items with each item having a link to the URL that provides more information about the state. Conceivably, these links might look something like https://example.com/orders/{orderId}/items/{itemId}, but with a hypermedia API, it's entirely conceivable that this API could be moved to https://example.com/items/{itemId} without any sort of change to the frontend, since the client is only aware of this link via hypermedia link. In this case, a contract with this items api might still make a lot of sense, but hardcoding that link in the contract doesn't make sense because the consumer is never aware of the specifics of the URL in the first place. This makes it seem like PACT and hypermedia links don't work well together, or at the very least, that the PACT might need to know more about the endpoint than the client itself does.

However, it seems like the pact V3 specification (and every library that implements it) has a way to inject provider state into a a contract. In this way, a consumer contract might specify basically that given that an item exists, and using the link to access it that the provider provides, the response should look a certain way. However, lots of the documentation seems to stop short of this most extreme case of providing the entire URL via provider state callbacks. Is there a reason for that? Is pursuing this going to end up being a bad idea?

@rholshausen
Copy link
Contributor

rholshausen commented Jan 13, 2023

I use Pact tests to test the interaction between the Pact frameworks and the Pact Broker, which uses HAL. The URLs are just like IDs, they are not important and should not be stored in the contracts. The sequence of payloads and the IDs of the links are important. So injecting the URLs via any means is fine in my book, as long as you are not changing the sequence of payloads.

Now, for example, when we validate a Pact file, we need to send the validation results back to the Pact Broker. We do this by fetching the Pact file via it's URL, get all the links and look for the link with ID pb:publish-verification-results. So in the test, I can use a mock server and replace the URLs, as long as the link with that ID points to the correct resource.

So the contract is about the sequence Pact URL -> Link pb:publish-verification-results -> verification-results Resource. The actual URLs can be anything.

Siren makes this a bit better, because it deals with actions on resources. So your test would be on the sequence URL -> action -> URL -> action -> URL and, again, the actual URLs are not important for the contract.

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

No branches or pull requests

2 participants