7

Where trying to improve the "confidence" we have in our inter-service communication.

Background: "Contracts" has been a matter of sharing a piece of code that defines an interface to implement, but over the years, the shared code changed, and a lot of different implementations (soap, msmq, rest etc.) sprouted up, which could all be said to implement the same interface, but in no way plays well together, whithout mapping, which caused a forest of "mapping" microservices to be implemented, which again, appears in different version. Development and Operations are both suffering from this.

Intention: I would like to define contracts for the endpoints on the outside, using something like Swagger or API blueprint. With swagger i can compare the swagger.json "contract" with the swagger.json for the service claiming to implement it, and with API blueprint, theres "dredd". For MSMQ based transports, we'll need some other approach, but i think contracts for the structure inside the messages could/should be conformed to for the same reasons as the http-endpoints.

The details about how to verify is not the question - the question is: How would you organize these contracts? Should we have an internal repository of contracts that can never be changed, but only occur in new versions, and then have the verification-process be told which contracts are (supposedly) implemented? Said contract-repo should be read-accessible by our verification-process, and to our (and external) developers...

Any inputs regarding the problems described in the background is appreciated, maybe I'm looking the wrong way for a solution?

  • 1
    This is an interesting post. Some questions are appropriate... What is the end-goal? Are we trying to allow a service or app the ability to discover APIs/endpoints that are available and the arguments and return values those APIs/endpoints accept and expect and deliver? How will the repository be indexed and accessed? Will a human/programmer browse the repository or will there be direct lookups for a keyword or string? Will APIs/endpoints be categorized or searchable? If you could provide a use-case it would be helpful in developing an answer/solution. – Midwire Dec 29 '15 at 17:05
  • Good questions. I'll have to use a couple of comments... The primary goal is to build an index of dependable services, and use the formality regarding "what is dependabel (ie. what does the contract promise) as a blackbox test-fixture for the developers. A more long-term goal would definitely be service-discovery. The end-goal is an infrastucture we can reasonably rely on, and prevent "chain-of-breaking-changes" and maintenance nightmare. – Julian Dec 30 '15 at 14:24
  • A human-readable interface for the repository would be nice, I think being able to see the contract-definitions will help developers earlier, rather than just a negative feedback on build/test. – Julian Dec 30 '15 at 14:24
  • The api's needs to be categorized in at least 3 dimensions: Transport protocol (as this has a huge impact on how to outside-in verify the correctness of the contract-implementation), the service of the contract (what is the expected affect of calling a service implementing this contract - using a name like "booking" or "sms-sending" should suffice), and the version of the contract. The last part is important, because we may very well have service X implementing contract "A" v1. & v.2 (for backwards compatibility), and service Y implementinc contract "A" v. 2 and contract "B" v1. – Julian Dec 30 '15 at 14:25
  • A reverse lookup on this could be used for discovery. Client needs a service conforming to contract "C" v. 3,4 or 5, and asks the (what we're talking about) for such services. – Julian Dec 30 '15 at 14:25
1
+50

The simplest solution IMO would be to utilize Pull Requests and good automated test coverage. It is a paradigm shift for those who are not used it but the the benefits are undeniable.

Github has some good docs: https://help.github.com/articles/creating-a-pull-request/ as does BitBucket: https://www.atlassian.com/git/tutorials/making-a-pull-request/

PRs only work when the entire team is on board. When a new PR is submitted, all developers except those on the critical path should stop what they are doing and take a few minutes to review the PR and leave comments like: this code will break the current contract for the Xyz method, please revisit or looks good. Many developers will simply leave a +1 if they think the code should be merged. Once you get enough eyes and approvals on the code it can be merged into the development branch.

In addition I would definitely make sure the team maintains good automated tests.

If you don't use git, Github or BitBucket and are unable or unwilling to change...

You could approach this in a couple different ways:

  1. An internal system: This would generate and serve up API/Endpoint documentation based on method signatures and comments. You could use an automated tool to generate the documentation in HTML format. The problem with this is that the developers can easily change the contracts (method signatures) and commit that code which breaks things. The benefit would be virtually zero maintenance and a readable/searchable interface for developers to discover existing endpoint contracts.

  2. An external system: This sounds more like what you want. You could do this in several different ways. One way would be to use a documentation tool like Yard to generate the current baseline docs, then assign the task of modifying them whenever a contract needs to change. Doing it this way would allow you to setup a separate (external) web stack as a service. Another way would be to build a separate app that models the functionality you desire. It would have Klass and Method models. The disadvantage would be that someone would have to maintain it. The advantage would be that developers could not easily change the contracts, or at all if you restrict access to the code.

Based on your use cases above, I would tend to go with a separate app. You could have a maintenance interface for a Team Lead or Admin to change a contract and version of the API/Endpoint. You could also have a read-only interface for developers to lookup things.

Workflow:

  • Bug arrives at developers desk.
  • Developer finds the root of the problem in a particular method.
  • Developer looks up the method on the external contract site and discovers that the return value needs to change which will break the contract.
  • Developer brings the discovery to the Team Lead or change control board
  • Team Lead assigns developer to also modify the code that will break due to the change, accordingly
  • Developer writes code to fix the bug (and hopefully automated tests)
  • At this point the developer should be running a full regression test suite to make sure none of the new code has broken anything unexpected.
  • Developer commits the (tested) bug fix
  • Thanks for the input. We are automating tests for the new core services, and using git for them - It's the enormous amount of legacy "microservices" in an old TFS repo and outsourced developers that's causing the problems described here... Followup is severely expensive an ineffective, so the less change the better (while we pee our pants to keep warm). Thanks again! – Julian Jan 4 '16 at 10:02
  • I understand your pain. Glad it helped. – Midwire Jan 4 '16 at 18:54
0

I ended up doing this, using tests as internal dev-documentation for the contracts https://gist.github.com/JulianMay/899d7cc7a82f1ca7c893547d37732f86

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.