bacheca/transport.go

80 lines
1.8 KiB
Go

package bacheca
import (
"context"
"errors"
"fmt"
"net/http"
"strings"
proto "git.abbiamoundominio.org/hamcha/bacheca/proto"
"git.fromouter.space/Artificiale/moa/sd"
"github.com/go-kit/kit/log"
httptransport "github.com/go-kit/kit/transport/http"
"github.com/gorilla/mux"
)
// Request errors
var (
ErrInvalidFormat = errors.New("invalid format (use 'rss', 'atom', 'json')")
)
// MakeHTTPHandler makes the service available via HTTP
func MakeHTTPHandler(svc Service, logger log.Logger) http.Handler {
r := mux.NewRouter()
options := []httptransport.ServerOption{
httptransport.ServerErrorLogger(logger),
httptransport.ServerErrorEncoder(encodeError),
}
r.Methods("GET").Path("/feed").Handler(httptransport.NewServer(
getFeedEndpoint(svc),
decodeFeedRequest,
encodeFeedResponse,
options...,
))
sd.RegisterHealthHandler(r)
return r
}
func decodeFeedRequest(_ context.Context, r *http.Request) (interface{}, error) {
url := r.URL.Query()
request := proto.GetFeedRequest{
FeedType: proto.GetFeedRequest_RSS,
}
if typ := url.Get("type"); typ != "" {
ftype := strings.ToUpper(typ)
fid, ok := proto.GetFeedRequest_FeedType_value[ftype]
if !ok {
return nil, ErrInvalidFormat
}
request.FeedType = proto.GetFeedRequest_FeedType(fid)
}
return request, nil
}
func encodeFeedResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
resp := response.(proto.GetFeedResponse)
_, err := fmt.Fprint(w, resp.Data)
return err
}
func encodeError(_ context.Context, err error, w http.ResponseWriter) {
if err == nil {
panic("encodeError with nil error")
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(codeFrom(err))
}
func codeFrom(err error) int {
switch err {
case ErrInvalidFormat:
return http.StatusBadRequest
default:
return http.StatusInternalServerError
}
}