An HTTP response code tells a client how a server handled its request. Check it before parsing a response body: an unsuccessful exchange-rate request should not be treated as valid rate data. section 6.5.4
The first digit identifies the broad result:
- 1xx: the request was received and processing continues. section 6.5.4
- 2xx: the request succeeded. Common choices include 200 OK, 201 Created, 202 Accepted for later processing, and 204 when there is no content to return. section 6.5.4 section 8.2.1
- 3xx: further action is needed to complete the request. section 6.5.4
- 4xx: the request has a client-side problem; 5xx: the server failed to fulfill an apparently valid request. section 6.5.4
Listing 6.41 ecb.go: Function handling the HTTP status code
const (
clientErrorClass = 4
serverErrorClass = 5
)
// checkStatusCode returns a different error
// depending on the returned status code.
func checkStatusCode(statusCode int) error {
switch {
case statusCode == http.StatusOK: #1
return nil
case httpStatusClass(statusCode) == clientErrorClass: #2
return fmt.Errorf("%w: %d", ErrClientSide, statusCode)
case httpStatusClass(statusCode) == serverErrorClass: #3
return fmt.Errorf("%w: %d", ErrServerSide, statusCode)
default: #4
return fmt.Errorf("%w: %d", ErrUnknownStatusCode, statusCode)
}
}
// httpStatusClass returns the class of a http status code.
func httpStatusClass(statusCode int) int {
const httpErrorClassSize = 100
return statusCode / httpErrorClassSize
}
For an exchange-rate client, checkStatusCode accepts exactly http.StatusOK. It groups 4xx and 5xx by dividing the numeric code by 100, returns distinct wrapped errors for those classes, and treats other codes as unexpected. section 6.5.4
Return a creation status
A POST /games handler returns 201 Created for a new game. Call w.WriteHeader(http.StatusCreated) before writing its JSON body: writing first implicitly sends 200 OK, and a later WriteHeader call is superfluous. A handler test can assert the recorder’s Code is http.StatusCreated; curl -v exposes the status line when checking the running service. section 8.2.1 section 8.7
Keep protocol codes at the API boundary. gRPC has its own status codes: a service can translate a domain not-found error into codes.NotFound rather than making domain logic return a transport-specific code. section 10.3.1 section 10.7.3










