DiUS / pact-consumer-js-dsl

*DEPRECATED* A Javascript DSL for creating pacts, superceded by Pact JS
https://github.com/pact-foundation/pact-js
Other
56 stars 26 forks source link

Nodejs support #15

Closed BenSayers closed 9 years ago

BenSayers commented 9 years ago

My team is interested in using Pact for some of our nodejs services and are looking options as to how we might go about this. Some of the options being explored:

I am interested in getting your thoughts and feedback before I dive in and start working on a solution.

Cheers, Ben

bethesque commented 9 years ago

Are the nodejs services a consumers or providers?

Someone else emailed me about using the DSL with a node consumer, and I suggested that they try https://github.com/driverdan/node-XMLHttpRequest. It's definitely the easiest option. The amount of work to implement the entire consumer side of pact in Javascript is what I would call "non trivial".

BenSayers commented 9 years ago

In Javascript we have both consumers and providers written in nodejs, as well as consumers written in client side Javascript.

I had considered node-XMLHttpRequest but the way they have implemented synchronous requests seems a bit hacky to me. They spawn off a separate process to actually do the request then put the main process in an busy loop waiting for the request to complete. https://github.com/driverdan/node-XMLHttpRequest/blob/master/lib/XMLHttpRequest.js#L488

I'm hesitant to push for mass adoption of Pact at my company built on top of a hacky solution and so would rather see a full implementation like already exists in Ruby, Java and .NET.

I'd like to get a better idea of whats involved in building a full consumer and provider for Javascript so I can see if its something I can contribute toward. Where is the best place to start?

bethesque commented 9 years ago

I am hesitant about writing a whole new pact implementation in JS, because there is significant effort in keeping all the implementations in line with each other. The .Net implementation is still early days and lacks proper "diff" displays, and the JVM impl is still not as feature complete as the Ruby one. The matching has to be done in exactly the same way in each implementation, otherwise, there is no confidence to be gained by saying that the pact is "verified."

If you would like to get an idea of what the work would be to create a JS implementation, please have a look at the the pact-specification repo. https://github.com/bethesque/pact-specification/tree/version-1.1 https://github.com/bethesque/pact-specification/tree/version-1.1/testcases https://github.com/bethesque/pact-specification/tree/master/implementation-guidelines

I am working on packaging the ruby mock server as a standalone executable using Travelling Ruby, so that we can pull the ruby dependency out of the consumer side of the JS DSL. A similar thing could be done for the provider verification.

BenSayers commented 9 years ago

I share your concerns with ensuring consistency between implementations in different languages.

In that case I think making this dsl compatible with nodejs is the best way forward. I'll give it a go and let you know how far I get.

bethesque commented 9 years ago

If it's really just the XMLHttp stuff, we could extract that out into a dependency that could be overridden. There's not much in the codebase at the moment, but there will be more when we add the support for the flexible matching.

bethesque commented 9 years ago

Though, being node, if it has to be all asynchronous, then maybe it's just better to maintain a separate codebase. Let me know what you think.

BenSayers commented 9 years ago

Correct, node does not provide a way to make synchronous http requests (that isn't a hack anyway).

This will require a change in the interface of MockService instances. The clean, setup, verify and write functions will need to change as they will become asynchronous. The given and uponReceiving functions do not need to change, and these seem to be the main entry points from the tests. And run already accepts a callback.

write is the only function that my tests were calling, and I notice you've just updated the code to make this call unnecessary. So I don't think this change will impact a typical test. All these methods are exposed however, so it is a breaking api change.

My opinion on if we should make a separate codebase is that it's better to have a consistent api between nodejs and the browser and so I would keep them the same.

Are you happy to change the api?

bethesque commented 9 years ago

Clean, setup, verify and write are only supposed to be called internally anyway, and are only exposed for testing purposes. I'm fine with them becoming asynchronous if it means we can get better code reuse.

bethesque commented 9 years ago

Sorry, I refactored the things :(