Updating README.md adding 'System-generated error responses' and 'Panic recovery in other goroutines' sections.
All checks were successful
Deploy Greenlight API / deploy (push) Successful in 59s
All checks were successful
Deploy Greenlight API / deploy (push) Successful in 59s
This commit is contained in:
34
README.md
34
README.md
@@ -100,6 +100,40 @@ So, if we want to customize how something is encoded, all we need to do is imple
|
|||||||
|
|
||||||
An example is available here : **internal/data/runtime.go**
|
An example is available here : **internal/data/runtime.go**
|
||||||
|
|
||||||
|
### System-generated error responses
|
||||||
|
|
||||||
|
In certain scenarios Go's **http.Server** may still automatically generate and send plain-text HTTP responses. These scenarios include when :
|
||||||
|
|
||||||
|
- The HTTP request specifies an unsupported HTTP protocol version.
|
||||||
|
- The HTTP request contains a missing or invalid **Host** header, or multiple **Host** headers.
|
||||||
|
- The HTTP request contains an empty **Content-Length** header.
|
||||||
|
- The HTTP request contains an unsupported **Transfer-Encoding** header.
|
||||||
|
- The size of the HTTP request headers exceeds the server's **MaxHeaderBytes** setting.
|
||||||
|
- The client makes a HTTP request to an HTTPS server.
|
||||||
|
|
||||||
|
For example, if we try sending a request with an invalid **Host** header value, we will get a response like this:
|
||||||
|
|
||||||
|
`$ curl -i -H "Host: こんにちは" http://localhost:4000/v1/healthcheck
|
||||||
|
HTTP/1.1 400 Bad Request: malformed Host header
|
||||||
|
Content-Type: text/plain; charset=utf-8
|
||||||
|
Connection: close
|
||||||
|
|
||||||
|
400 Bad Request: malformed Host header`
|
||||||
|
|
||||||
|
Unfortunately, these responses are hard-coded into the Go Standard library, and there's nothing we can do to customize them to use JSON instead.
|
||||||
|
|
||||||
|
But while this is something to be aware of, it's not necessarily something to worry about. In a production environment it's relatively unlikely that well-behaved, non-malicious, clients would trigger these responses anyway, and we shouldn't be overly concerned if bad clients are sometimes set a plain-text response instead of JSON.
|
||||||
|
|
||||||
|
### Panic recovery in other goroutines
|
||||||
|
|
||||||
|
It's important to realize that our middleware will only recover panics that happen in the _same goroutine that executed the **recoverPanic()** middleware_.
|
||||||
|
|
||||||
|
If, for example, you have a handler which spins up another goroutine (e.g. to do some background processing), then any panics that happen in the background goroutine will not be recovered - not by the **recoverPanic()** middleware... and not by the panic recovery build into **http.Server**. These panics will cause your application to exit and bring down the server.
|
||||||
|
|
||||||
|
So, if you are spinning up additional goroutines from within your handlers and there is any chance of a panic, you **must make sure** that you recover any panics from within those goroutines too.
|
||||||
|
|
||||||
|
A demonstration will follow when we will use a background goroutine to send welcome emails to our API users.
|
||||||
|
|
||||||
### Performance
|
### Performance
|
||||||
|
|
||||||
json.MarshalIndent() takes 65% longer to run and uses around 30% more memory than json.Marshal(), as well as making two more heap allocations. Those figures will change depending on what you're encoding, but they're fairly indicative of the performance impact.
|
json.MarshalIndent() takes 65% longer to run and uses around 30% more memory than json.Marshal(), as well as making two more heap allocations. Those figures will change depending on what you're encoding, but they're fairly indicative of the performance impact.
|
||||||
|
|||||||
Reference in New Issue
Block a user