This client library describes classes to wrap service responses to separate network responses, such as HTTP response codes, from the service response information. A service response code is wrapped, with an optional result object or optional error objects.
$ dotnet add package IntAlt.ResponseWrappersThis library describes classes used to return responses from endpoints from services and microservices.
Best is a nebulously defined term. It can be cheapest, easiest, simplist, most cpu or power efficient, or all or none of these.
For our purposes, Best Practices are my opinionated views and experience on returning values from service and microservice endpoints - especially REST services.
One annoying limitation is the need to put a constraint on the generic T. I have no doubt that someone familiar with the Roslyn compiler can explain why, but C# doesn't like allowing a nullable type that can be either a class or a struct. Because of this, the default Response is required to be a constrained to a class. A separate set of classes, ResponseStruct and DetailedResponseStruct are available.
When developers decide to use HTTP response codes to indicate responses from their service endpoints, it can be confusing. If a 404 error indicating that the endpoint is not found or does it indicate that the call returned 0 records, when 1 was expected.
This library was created numerous times throughout my career to deal with this situation. It makes the following optionated assumptions:
These are not required or enforced by the library. They are simply best practices observed in development.
Response code '0' is a generalized success code. It typically means that the request was successful and everything ran through the "happy path" as expected.
Positive response codes (greater than 0) also indicate success, although not necessarily through the expected path.
For example, an API call to "_change record with identifier {id} so that the status is "PENDING" could return a positive value indicating that nothing was done because the record was ALREADY marked as pending. The result after the API call was what the caller wanted, but nothing was actually changed.
Negative value response codes indicate some sort of error. Typically, response codes from -1 to -99 are generalized, system wide errors, with -1 being reserved for "Something completely unexpected occurred". Then, other codes are grouped by backend services. Examples include:
The ranges are irrelevent - experience has shown that grouping can help with debugging, since knowing which range belongs to which service can speed up debugging a bit. Service B, above, has 2 ranges. This can occur if a service is initially given a range, and the number of response codes exceeds that range or if the developers wish to specify that no range group will exceed 100 items.
The base class is the Response class. It is a simple wrapper around a
response code. The generic class Response<T> returns a code and,
optionally, some sort of response value - such as database record. The
DetailedResponst<T> class returns more detailed error information.
This is a simple class that just contains a return code. This is useful when your response is a simple response code.
A child class of the Response class. Includes a Result of type T, if specified.
Child class of the Response class. In addition to the Result, can contain more error detail information. This is useful for responding to a web front end where the error messages are human readable.
Used by the DetailedResponse and DetailedResponseStruct classes, the error class is useful to return more detailed information to the caller. Typically, this will be for returning human readable error information to a user interface.
This might change. The intention is as follows: