feat: migrate workbench services
This commit is contained in:
@@ -2,22 +2,15 @@ package httpapi
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.118im.com/im_team/im_workbench/internal/auth"
|
||||
"git.118im.com/im_team/im_workbench/internal/store"
|
||||
)
|
||||
|
||||
const (
|
||||
reasonMalformedRequest = "MALFORMED_REQUEST"
|
||||
reasonMethodNotAllowed = "METHOD_NOT_ALLOWED"
|
||||
reasonAuthRequired = "AUTH_REQUIRED"
|
||||
reasonForbidden = "FORBIDDEN"
|
||||
reasonNotFound = "RESOURCE_NOT_FOUND"
|
||||
reasonConflict = "CONFLICT"
|
||||
reasonValidationFailed = "VALIDATION_FAILED"
|
||||
reasonInternal = "INTERNAL"
|
||||
)
|
||||
|
||||
@@ -32,44 +25,20 @@ type apiError struct {
|
||||
|
||||
func writeSuccess(w http.ResponseWriter, r *http.Request, data any) {
|
||||
writeJSON(w, r, http.StatusOK, map[string]any{
|
||||
"code": 0,
|
||||
"data": data,
|
||||
"request_id": requestID(r),
|
||||
"code": 0, "data": data, "request_id": requestID(r),
|
||||
"server_time": time.Now().UTC().Format(time.RFC3339Nano),
|
||||
})
|
||||
}
|
||||
|
||||
func writeError(w http.ResponseWriter, r *http.Request, status, code int, reason, message string, details map[string]any) {
|
||||
writeJSON(w, r, status, apiError{
|
||||
Code: code,
|
||||
Reason: reason,
|
||||
Message: message,
|
||||
Details: details,
|
||||
RequestID: requestID(r),
|
||||
ServerTime: time.Now().UTC().Format(time.RFC3339Nano),
|
||||
})
|
||||
}
|
||||
|
||||
func writeStoreError(w http.ResponseWriter, r *http.Request, err error) {
|
||||
switch {
|
||||
case errors.Is(err, ErrNotFound), errors.Is(err, store.ErrNotFound):
|
||||
writeError(w, r, http.StatusNotFound, 30004, reasonNotFound, "resource not found", nil)
|
||||
case errors.Is(err, ErrForbidden), errors.Is(err, store.ErrForbidden), errors.Is(err, auth.ErrForbidden):
|
||||
writeError(w, r, http.StatusForbidden, 30041, reasonForbidden, "forbidden", nil)
|
||||
case errors.Is(err, ErrConflict), errors.Is(err, store.ErrConflict):
|
||||
writeError(w, r, http.StatusConflict, 30040, reasonConflict, "conflict", nil)
|
||||
case errors.Is(err, store.ErrPolicy):
|
||||
writeError(w, r, http.StatusBadRequest, 30000, reasonValidationFailed, "validation failed", nil)
|
||||
default:
|
||||
writeError(w, r, http.StatusInternalServerError, 90000, reasonInternal, "internal error", nil)
|
||||
}
|
||||
writeJSON(w, r, status, apiError{Code: code, Reason: reason, Message: message, Details: details,
|
||||
RequestID: requestID(r), ServerTime: time.Now().UTC().Format(time.RFC3339Nano)})
|
||||
}
|
||||
|
||||
func writeJSON(w http.ResponseWriter, r *http.Request, status int, value any) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
w.Header().Set("X-IM-Schema", firstNonEmpty(r.Header.Get("X-IM-Schema"), "1"))
|
||||
if rid := requestID(r); rid != "" {
|
||||
w.Header().Set("X-Request-ID", rid)
|
||||
if requestID := requestID(r); requestID != "" {
|
||||
w.Header().Set("X-Request-ID", requestID)
|
||||
}
|
||||
w.WriteHeader(status)
|
||||
_ = json.NewEncoder(w).Encode(value)
|
||||
@@ -79,20 +48,21 @@ func requestID(r *http.Request) string {
|
||||
return r.Header.Get("X-Request-ID")
|
||||
}
|
||||
|
||||
func firstNonEmpty(values ...string) string {
|
||||
for _, value := range values {
|
||||
if value != "" {
|
||||
return value
|
||||
}
|
||||
func decodeBody(w http.ResponseWriter, r *http.Request, dst any) bool {
|
||||
defer r.Body.Close()
|
||||
decoder := json.NewDecoder(r.Body)
|
||||
decoder.DisallowUnknownFields()
|
||||
if err := decoder.Decode(dst); err != nil {
|
||||
writeError(w, r, http.StatusBadRequest, 30000, reasonMalformedRequest, "malformed request", nil)
|
||||
return false
|
||||
}
|
||||
return ""
|
||||
return true
|
||||
}
|
||||
|
||||
func firstNonNilInt64(values ...*int64) *int64 {
|
||||
for _, value := range values {
|
||||
if value != nil {
|
||||
return value
|
||||
}
|
||||
func methodNotAllowed(w http.ResponseWriter, r *http.Request, allowed ...string) {
|
||||
if len(allowed) == 0 {
|
||||
allowed = []string{http.MethodPost}
|
||||
}
|
||||
return nil
|
||||
w.Header().Set("Allow", strings.Join(allowed, ", "))
|
||||
writeError(w, r, http.StatusMethodNotAllowed, 30005, reasonMethodNotAllowed, "method not allowed", nil)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user