xmidt-org / wrp-go

go implementation of the Web Routing Protocol
Apache License 2.0
4 stars 7 forks source link

Add a standard way of decoding a *http.Request into a message #115

Closed johnabass closed 1 year ago

johnabass commented 1 year ago

Currently, we have a way of decoding to a wrphttp.Entity. But we need a lower-level way of decoding an *http.Request that can work for servers that don't use a wrp.Handler.

The basic API should leverage a general context-based approach, as in https://github.com/xmidt-org/wrp-go/issues/114. From a client's POV, this can look like:

// DecodeRequest uses the request's context like a cache, decoding only when necessary
// The returned request is useful when decorating HTTP handlers, but otherwise can be discarded
var msg *wrp.Message
request, err := wrphttp.DecodeRequest(request, &msg)

A skeleton implementation of DecodeRequest can look something like:

func DecodeRequest(request *http.Request, msg any) (*http.Request, error) {
    // this assumes issue 114 has been implemented, supporting any kind of message
    if wrpcontext.GetAs(request.Context(), msg) {
        // the context already contains a message, so just return the original request
        return request, nil
    }

    // NOT SHOWN: use the `wrp` and `wrphttp` packages to decode the message
    // remember: you have to support the "HTTP header format" as well
    var decodedMessage *wrp.Message
    ctx := wrpcontext.Set(request.Context(), decodedMessage)

    // a new request with the new context, containing the decoded message
    // this makes sure that any other server-side calls to this function won't need
    // to decode the message again
    return request.WithContext(ctx), nil