Service Output Architecture

Exploring service-based computing, specifically Function as a Service, raises questions about standardizing the output contract for uniform, predictable service behavior.

Service Output Architecture
💡
Note: this post was imported from my previous version of the blog as I still find value in referring back to this chart of Service Operations to HTTP Status codes and outcomes (with some minor grammar updates)

Exploring service-based computing, specifically Function as a Service, raises questions about standardizing the output contract for uniform, predictable service behavior. Key to this discussion are the potential outcomes:

Successful Outcomes

Successful: Is the most basic successful response and indicates that whatever was expected to occur as the happy path, occurred.

Created: this status could be returned if a new resource was created in the course of the service operation, and we need to indicate that the resource was created back to the caller.

Fulfilled by existing resource: The idea here is that the request, as provided matches precisely with an existing resource and the previous resource can be safely returned. An example, might be storing a phone number. If the request is to store a number and the previous number already exists then we can return this status code as a way to indicate that the request was successful but that no changes were made. This helps the calling code to decide what to do with this information. For example, can provide a level of idempotency support.

Queued: The request was received but is being queued for future processing. There is an assumption of future processing but at this point there is no guarantee. The caller would need to use to another method to validate the success of the call (e.g. postback, or polling a retrieval service).

Failed Outcomes

The failure states come from three potential areas:

  • Business or Logic Errors - that are expected and planned for.
  • System Errors - these are unexpected errors and not planned for
  • Upstream Errors - these are errors that are outside of the direct control of the service.

Business or Logic Errors

Resource not found: This status is returned if the was a request for a specific resource to retrieve or modify and the resource does not exist.

Validation error: This status indicates that something was wrong with the request payload, or the intent of the call. E.g. it could be that a parameter was not correct in the input payload, or this could also indicate a business error. In either case there is an assumption that response message will provide useful information in relation to the specific issue that is causing the error. In the case of a malformed request the information provided in the response object should be sufficient to allow the user to correct the error. For a business error there may or may not be something the caller can do to recover the error, but the error should exist due a problem with the request message.

Conflicting request error: In this scenario the caller is providing a request object that would conflict with an existing resource, or state of an existing resource and cannot be reconciled automatically. This could be due to a duplicate object being created, or a business logic error that is preventing the service from completing as expected.

System Errors

Transient and Permanent error: In each case the error is system related not business related. If retrying the request could succeed, then the transient status is returned.

Rate Limited: If the service has controls for number of requests, then the service could return this status if that rate is exceeded.

Dependency Errors

Upstream timeout: If this service has a dependency and an upstream service had timed out then this service will not know the true state of the upstream dependency. If that scenario is not handled internally then the service will report the timeout.

Upstream error: This service may rely on other services (both internal and vendor). Upstream errors should be treated similarly to transient errors; however, the source of the error is external to the service being called.

Supporting HTTP Web APIs

As the service can be used inside of a web API we should determine what appropriate HTTP status code should be returned based on the service result. It is no coincidence that there is almost a 1-1 match with an existing HTTP status code.