2

In this scenario there are two HTTP microservices:

  1. The public service that provides the client with data
  2. The internal microservice that authenticates calls to the public service

Service 1 makes a call to Service 2 to ask it to authenticate the token provided to it by the client.

The agreement ("contract") is that Service 2 should reply with 200 OK and JSON content about the authenticated user.

In Service 1, if it receives the response 200 OK, is it worth going any further to validate the response further?

For example, the JSON body of the response is parsed into an object. Is there value in checking if that object was correctly instantiated instead of being set to null? Or alternatively should that be left to integration tests?

edev
  • 91
  • 1
  • 6
  • What is the content of this object? Does service 1 use it? –  Jul 19 '16 at 09:00
  • Yes, Service 1 does use the content of the response. It includes the `UserID`. – edev Jul 19 '16 at 09:44
  • Related reference to testing approaches for microservices: http://martinfowler.com/articles/microservice-testing/ – edev Jul 19 '16 at 09:44

2 Answers2

0

Strictly, a 200 only means that the request was successfully processed. This is regardless of the actual outcome of the call from a business perspective.

You are in effect relying on a convention of "we will throw an exception or otherwise fail the call if the user is not authenticated", to authenticate users.

Depending on the convention, you could conceivably have a scenario where a user was unauthenticated but the call was still successfully processed.

From this perspective, it may be worth having the service2 return a response which could then be interrogated to close this circle.

Alternatively, you could have the client call the authentication service directly, retrieve a token, and then present this token with any other request. This would mean that service1 is no longer responsible for having to know that a caller is authenticated.

The question is whether or not to then test in Service 1 each time the response is received

Sorry, I would appear to have misunderstood the spirit of the question somewhat.

I am slightly confused - are you asking that, if the system under test is service1 then should any response from service2 also be part of that test?

I would say you would have to have some test which could prove that the sercvice2 response interrogation logic is correct, but this could be done at the unit test level. I don't think you'd need to do this for tests running against a deployed instance of the service, which is by nature more about the service behaviour at the boundary rather than internally.

tom redfern
  • 30,562
  • 14
  • 91
  • 126
  • "From this perspective, it may be worth having the service2 return a response which could then be interrogated to close this circle." That is indeed what Service 2 does. The question is whether or not to then test in Service 1 each time the response is received, to verify it contains an expected attribute. (The other side of the argument is not to bother in each live request, and leave that to integration testing.) – edev Jul 19 '16 at 10:41
0

Well your approach is not that bad!

Some of the HTTP status codes are reserved for cases of malformed requests etc. but in your case, you ask Service2 to return information for a token! If that token exists, you specified correctly, that Service2 has to return 200 OK. Now you just need to specify what happens if the token is not valid anymore or if it does not exists (or treat both cases the same...). If you specify, that Service2 has to return 404 Not found if it does not know the token or that the token expired, there (in most cases) is no need for Service1 to go any further! Parsing the status code is cheap in almost any language/environment, but forcing the deserialization of the content in both success and error cases is in comparison very expensive. Authentication needs to be fast - so I'd go for the status code here!

The key is, that this behavior has to be specified somewhere! (We went for swagger definitions!)

enzian
  • 733
  • 5
  • 13
  • Thanks, and good tip on Swagger. To be clear, I need to parse the response body for the user ID. So it's a question of doing that and assuming I now have an object with the user ID, or doing an explicit check and throwing an exception if that attribute was not returned. – edev Jul 19 '16 at 12:34