Earlier today I was asked to diagnose an issue in some development code. It turned out that the issue was caused by a new stub implementation returning random data which did not match the service specification.
This led to a conversation with other with regards to the correct approach to dealing with this scenario and a number of different view points and I am curious as to what others would say.
The service specification documents states that for this field, we will return nothing, ‘A’ or ‘D’. (optional/string(1))
The stub had been setup at that point to return a value of ‘8whMJiAIIg’, which matched the WSDL definition (string).
We use a pattern that exposes a (wcf/.NET)response object that is populated from the response of the service/stub (translated accordingly) and the implementation of this was written as per the service spec and was checking for the existence of A or D or not returning anything.
Ultimately, because the value was not A or D which it needed to be in this scenario, the code did not return some additional data and it was causing an exception later in the flow.
The conversation went onto Defensive coding and this is where we are split.
So my question is this;
Should we rely on the service implementation/stub to return data as per the spec (this is considered to be an internal, trusted service) or should we always put code in to confirm that the data sent is indeed as per the service spec.
If you have a schema that defines what a valid message is, your software should be able to accept everything that is valid from the perspective of the schema, even if it doesn’t make sense in the context of your application. One of the first things you do upon receiving a message is to validate it’s correctness.
If there are further restrictions placed on the contents of the schema that aren’t captured in the schema, you should try to put them in the schema. Sometimes, it may not be possible, such as the schema being shared across a wide variety of applications with different internal rules. In this case, applications should add their own validation of the received messages and fail quickly if an invalid message is received.
In short – you should always check. You should also move whatever checks you can do the definition of the message so it becomes hard for anyone using your message definition to send a bad message and easy for applications to validate the contents of the message.
If it’s internal then validation isn’t necessary. If it’s external then validation is necessary.
However; “internal” means within the same piece of code; where if one piece is replaced you expect the whole thing (everything internal) to be replaced at the same time.
For “part A communicates with Part B via. anything involving sockets”, it’s external. In that case it’s not a question of whether you need validation; it’s a question of whether you need authentication and encryption (e.g. to defend against “man in the middle” attacks) in addition to validation.
For an internal, trusted service, I would rely on the specs, assuming you have a way to catch this quickly if it happens, with the help of unit tests.
If this was an external service that could be used by a third-party, then you would need to add validation to confirm that the data sent is based on the specs.