feat: add go realtime redis api
This commit is contained in:
69
go/vehicle-gateway/internal/realtime/http.go
Normal file
69
go/vehicle-gateway/internal/realtime/http.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package realtime
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
|
||||
"lingniu-vehicle-ingest/go/vehicle-gateway/internal/envelope"
|
||||
)
|
||||
|
||||
type Handler struct {
|
||||
repository *Repository
|
||||
}
|
||||
|
||||
func NewHandler(repository *Repository) *Handler {
|
||||
if repository == nil {
|
||||
panic("realtime repository must not be nil")
|
||||
}
|
||||
return &Handler{repository: repository}
|
||||
}
|
||||
|
||||
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodGet {
|
||||
writeError(w, http.StatusMethodNotAllowed, "method not allowed")
|
||||
return
|
||||
}
|
||||
path := strings.Trim(strings.TrimPrefix(r.URL.Path, "/api/realtime/vehicles/"), "/")
|
||||
parts := strings.Split(path, "/")
|
||||
if len(parts) == 0 || strings.TrimSpace(parts[0]) == "" {
|
||||
writeError(w, http.StatusNotFound, "vehicle not found")
|
||||
return
|
||||
}
|
||||
vin := parts[0]
|
||||
switch {
|
||||
case len(parts) == 1:
|
||||
snapshot, err := h.repository.GetMerged(r.Context(), vin)
|
||||
writeResult(w, snapshot, err)
|
||||
case len(parts) == 2 && parts[1] == "online":
|
||||
status, err := h.repository.IsOnline(r.Context(), vin)
|
||||
writeResult(w, status, err)
|
||||
case len(parts) == 3 && parts[1] == "protocols":
|
||||
snapshot, err := h.repository.GetProtocol(r.Context(), vin, envelope.Protocol(strings.ToUpper(parts[2])))
|
||||
writeResult(w, snapshot, err)
|
||||
default:
|
||||
writeError(w, http.StatusNotFound, "route not found")
|
||||
}
|
||||
}
|
||||
|
||||
func writeResult(w http.ResponseWriter, value any, err error) {
|
||||
if err != nil {
|
||||
if errors.Is(err, redis.Nil) {
|
||||
writeError(w, http.StatusNotFound, "not found")
|
||||
return
|
||||
}
|
||||
writeError(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_ = json.NewEncoder(w).Encode(value)
|
||||
}
|
||||
|
||||
func writeError(w http.ResponseWriter, status int, message string) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(status)
|
||||
_ = json.NewEncoder(w).Encode(map[string]any{"error": message})
|
||||
}
|
||||
Reference in New Issue
Block a user