0

I'm developing a service rest in Go using go-kit. I need send a header response. This header response should have the same value of request header.

This is a part of my transport.go:

func MakeHandler(m **http.ServeMux) http.Handler {
    const URL = "..."

    var serverOptions []kithttp.ServerOption

    logger := log.NewLogfmtLogger(os.Stderr)

    var svc repositories.SignDocumentRepository

    impl := persistence.NewSignerDocumentRepository()

    svc = middleware.LoggingMiddlewareSignDocument{Logger: logger, Next: impl}

    registerHandler := kithttp.NewServer(
        makeSignDocumentEndpoint(svc),
        decodeRequest,
        encodeResponse,
        serverOptions...,
    )

    r := mux.NewRouter()
    r.Handle(URL, handlers.LoggingHandler(os.Stdout, registerHandler))
    (*m).Handle(URL, r)

    return nil
}


func decodeRequest(_ context.Context, r *http.Request) (interface{}, error) {
    return r, nil
}

func encodeResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
    w.Header().Set("headerA", "val1")
    w.Header().Set("headerB", "") // This header should be equal that a header request
    switch response.(type) {
    case model.MsgRsHdr:
        w.WriteHeader(http.StatusPartialContent)
    default:
        w.WriteHeader(http.StatusAccepted)
    }
    if response != nil {
        return json.NewEncoder(w).Encode(response)
    }
    return nil
}

How do I get a request header in encodeResponse method?

1 Answer 1

3

You can use ServerBefore to put *http.Request in the context, and can get it in encodeResponse to read request headers.

type ctxRequestKey struct{}

func putRequestInCtx(ctx context.Context, r *http.Request, _ Request) context.Context {
    return context.WithValue(ctx, ctxRequestKey{}, r)
}

func encodeResponse(ctx context.Context, w http.ResponseWriter, response interface{}) error {
    r := ctx.Value(ctxRequestKey{}).(*http.Request)
    // can use r.Header.Get here to read request here.
}

serverOptions := []kithttp.ServerOptions{
    kithttp.ServerBefore(putRequestInCtx),
}

registerHandler := kithttp.NewServer(
        makeSignDocumentEndpoint(svc),
        decodeRequest,
        encodeResponse,
        serverOptions...,
)
Sign up to request clarification or add additional context in comments.

1 Comment

Is there any other clean way of achieving the same ? encodeResponse() ideally should just write in the ResponseWriter stream. Would it be right to use ServerAfter in such situations (here once again requestObj is not available).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.