-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Convert to HTTP handlers inside outside of the main package
Previously, the top-level package exported functions with the signature `func(*util.Context) util.StatusError`, and the `main` package was responsible for wrapping these and producing normal HTTP handlers. However, the Google Cloud Functions execution environment expects to be able to invoke HTTP handlers which are exported directly from the top-level package. We move the logic of converting these inner handlers into HTTP handlers to the `internal/util` package, allowing us to expose HTTP handlers from the top-level package
- Loading branch information
Showing
3 changed files
with
47 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package util | ||
|
||
import ( | ||
"encoding/json" | ||
"log" | ||
"net/http" | ||
) | ||
|
||
// Handler is a handler for a request to this service. Use MakeHTTPHandler to | ||
// wrap a Handler with the logic necessary to produce a handler which can be | ||
// registered with the "net/http" package. | ||
type Handler = func(ctx *Context) StatusError | ||
|
||
// MakeHTTPHandler wraps a Handler, producing a handler which can be registered | ||
// with the "net/http" package. The returned handler is responsible for: | ||
// - Constructing a *Context | ||
// - Converting any errors into an HTTP response | ||
func MakeHTTPHandler(handler func(ctx *Context) StatusError) func(http.ResponseWriter, *http.Request) { | ||
return func(w http.ResponseWriter, r *http.Request) { | ||
ctx, err := NewContext(w, r) | ||
if err != nil { | ||
writeStatusError(w, r, err) | ||
return | ||
} | ||
|
||
if err := handler(&ctx); err != nil { | ||
writeStatusError(w, r, err) | ||
} | ||
} | ||
} | ||
|
||
func writeStatusError(w http.ResponseWriter, r *http.Request, err StatusError) { | ||
type response struct { | ||
Message string `json:"message"` | ||
} | ||
|
||
w.Header().Set("Content-Type", "application/json; charset=utf-8") | ||
w.WriteHeader(err.HTTPStatusCode()) | ||
json.NewEncoder(w).Encode(response{Message: err.Message()}) | ||
|
||
log.Printf("[%v %v %v]: responding with error code %v and message \"%v\" (error: %v)", | ||
r.RemoteAddr, r.Method, r.URL, err.HTTPStatusCode(), err.Message(), err) | ||
} |