Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 46 additions & 39 deletions internal/devices/api/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,37 @@ import (
"github.com/kimanimichael/mk-device-manager/internal/devices"
"github.com/mike-kimani/fechronizo/v2/pkg/httpresponses"
"net/http"
"strconv"
)

const (
defaultOffset uint32 = 0
defaultLimit uint32 = 20
)

func parsePagination(r *http.Request) (uint32, uint32, error) {
offset := defaultOffset
limit := defaultLimit

if v := r.URL.Query().Get("offset"); v != "" {
parsed, err := strconv.ParseUint(v, 10, 32)
if err != nil {
return 0, 0, err
}
offset = uint32(parsed)
}

if v := r.URL.Query().Get("limit"); v != "" {
parsed, err := strconv.ParseUint(v, 10, 32)
if err != nil {
return 0, 0, err
}
limit = uint32(parsed)
}

return offset, limit, nil
}

type DeviceHandler struct {
service devices.DeviceService
}
Expand Down Expand Up @@ -57,22 +86,15 @@ func (h *DeviceHandler) CreateDevice(w http.ResponseWriter, r *http.Request) {
}

func (h *DeviceHandler) GetDeviceFromID(w http.ResponseWriter, r *http.Request) {
params := GetDeviceByIDRequest{}

decoder := json.NewDecoder(r.Body)
if err := decoder.Decode(&params); err != nil {
httpresponses.RespondWithError(w, http.StatusBadRequest, fmt.Sprintf("Request body could not be decoded as JSON: %v", err))
return
}

if params.ID == "" {
httpresponses.RespondWithError(w, http.StatusBadRequest, "ID field is required")
id := r.URL.Query().Get("id")
if id == "" {
httpresponses.RespondWithError(w, http.StatusBadRequest, "id query parameter is required")
return
}

ctx := r.Context()

device, err := h.service.GetDeviceByID(ctx, params.ID)
device, err := h.service.GetDeviceByID(ctx, id)
if err != nil {
httpresponses.RespondWithError(w, http.StatusInternalServerError, err.Error())
return
Expand All @@ -81,22 +103,15 @@ func (h *DeviceHandler) GetDeviceFromID(w http.ResponseWriter, r *http.Request)
}

func (h *DeviceHandler) GetDeviceFromUID(w http.ResponseWriter, r *http.Request) {
params := GetDeviceByUIDRequest{}

decoder := json.NewDecoder(r.Body)
if err := decoder.Decode(&params); err != nil {
httpresponses.RespondWithError(w, http.StatusBadRequest, fmt.Sprintf("Request body could not be decoded as JSON: %v", err))
return
}

if params.UID == "" {
httpresponses.RespondWithError(w, http.StatusBadRequest, "UID field is required")
uid := r.URL.Query().Get("device_uid")
if uid == "" {
httpresponses.RespondWithError(w, http.StatusBadRequest, "device_uid query parameter is required")
return
}

ctx := r.Context()

device, err := h.service.GetDeviceByUID(ctx, params.UID)
device, err := h.service.GetDeviceByUID(ctx, uid)
if err != nil {
httpresponses.RespondWithError(w, http.StatusInternalServerError, err.Error())
return
Expand All @@ -105,22 +120,15 @@ func (h *DeviceHandler) GetDeviceFromUID(w http.ResponseWriter, r *http.Request)
}

func (h *DeviceHandler) GetDeviceFromSerial(w http.ResponseWriter, r *http.Request) {
params := GetDeviceBySerialRequest{}

decoder := json.NewDecoder(r.Body)
if err := decoder.Decode(&params); err != nil {
httpresponses.RespondWithError(w, http.StatusBadRequest, fmt.Sprintf("Request body could not be decoded as JSON: %v", err))
return
}

if params.Serial == "" {
httpresponses.RespondWithError(w, http.StatusBadRequest, "Serial field is required")
serial := r.URL.Query().Get("device_serial")
if serial == "" {
httpresponses.RespondWithError(w, http.StatusBadRequest, "device_serial query parameter is required")
return
}

ctx := r.Context()

device, err := h.service.GetDeviceBySerial(ctx, params.Serial)
device, err := h.service.GetDeviceBySerial(ctx, serial)
if err != nil {
httpresponses.RespondWithError(w, http.StatusInternalServerError, err.Error())
return
Expand All @@ -142,15 +150,14 @@ func (h *DeviceHandler) GetDevices(w http.ResponseWriter, r *http.Request) {
}

func (h *DeviceHandler) GetPagedDevices(w http.ResponseWriter, r *http.Request) {
params := GetPagedDevicesRequest{}

decoder := json.NewDecoder(r.Body)
if err := decoder.Decode(&params); err != nil {
httpresponses.RespondWithError(w, http.StatusBadRequest, fmt.Sprintf("failed to decode request body"))
offset, limit, err := parsePagination(r)
if err != nil {
httpresponses.RespondWithError(w, http.StatusBadRequest, "Invalid offset or limit query parameter")
return
}

ctx := r.Context()
devicesPage, err := h.service.GetPagedDevices(ctx, params.Offset, params.Limit)
devicesPage, err := h.service.GetPagedDevices(ctx, offset, limit)
if err != nil {
httpresponses.RespondWithError(w, http.StatusInternalServerError, err.Error())
return
Expand Down
17 changes: 0 additions & 17 deletions internal/devices/api/requests.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,3 @@ type CreateDeviceRequest struct {
UID string `json:"uid"`
Serial string `json:"serial"`
}

type GetDeviceByIDRequest struct {
ID string `json:"id"`
}

type GetDeviceByUIDRequest struct {
UID string `json:"device_uid"`
}

type GetDeviceBySerialRequest struct {
Serial string `json:"device_serial"`
}

type GetPagedDevicesRequest struct {
Offset uint32 `json:"offset"`
Limit uint32 `json:"limit"`
}
75 changes: 43 additions & 32 deletions internal/messages/api/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,43 @@ package messagesapi

import (
"encoding/json"
"fmt"
"github.com/go-chi/chi"
"github.com/kimanimichael/mk-device-manager/internal/devices"
"github.com/kimanimichael/mk-device-manager/internal/messages"
"github.com/mike-kimani/fechronizo/v2/pkg/httpresponses"
"io/ioutil"
"net/http"
"strconv"
)

const (
defaultOffset uint32 = 0
defaultLimit uint32 = 20
)

func parsePagination(r *http.Request) (uint32, uint32, error) {
offset := defaultOffset
limit := defaultLimit

if v := r.URL.Query().Get("offset"); v != "" {
parsed, err := strconv.ParseUint(v, 10, 32)
if err != nil {
return 0, 0, err
}
offset = uint32(parsed)
}

if v := r.URL.Query().Get("limit"); v != "" {
parsed, err := strconv.ParseUint(v, 10, 32)
if err != nil {
return 0, 0, err
}
limit = uint32(parsed)
}

return offset, limit, nil
}

type MessageHandler struct {
service messages.MessageService
deviceService devices.DeviceService
Expand Down Expand Up @@ -71,22 +99,15 @@ func (h *MessageHandler) CreateMessage(w http.ResponseWriter, r *http.Request) {
}

func (h *MessageHandler) GetMessageByID(w http.ResponseWriter, r *http.Request) {
params := GetMessageByIDRequest{}

decoder := json.NewDecoder(r.Body)
if err := decoder.Decode(&params); err != nil {
httpresponses.RespondWithError(w, http.StatusBadRequest, fmt.Sprintf("Request body could not be decoded as JSON: %v", err))
return
}

if params.ID == "" {
httpresponses.RespondWithError(w, http.StatusBadRequest, "ID field is required")
id := r.URL.Query().Get("id")
if id == "" {
httpresponses.RespondWithError(w, http.StatusBadRequest, "id query parameter is required")
return
}

ctx := r.Context()

message, err := h.service.GetMessageByID(ctx, params.ID)
message, err := h.service.GetMessageByID(ctx, id)
if err != nil {
httpresponses.RespondWithError(w, http.StatusInternalServerError, err.Error())
return
Expand All @@ -101,25 +122,20 @@ func (h *MessageHandler) GetDeviceMessagesByUID(w http.ResponseWriter, r *http.R
return
}

params := GetMessagesRequest{}
decoder := json.NewDecoder(r.Body)
if err := decoder.Decode(&params); err != nil {
httpresponses.RespondWithError(w, http.StatusBadRequest, fmt.Sprintf("Request body could not be decoded as JSON: %v", err))
return
}
if params.Limit == 0 {
httpresponses.RespondWithError(w, http.StatusBadRequest, "Limit field is required")
offset, limit, err := parsePagination(r)
if err != nil {
httpresponses.RespondWithError(w, http.StatusBadRequest, "Invalid offset or limit query parameter")
return
}

ctx := r.Context()
_, err := h.deviceService.GetDeviceByUID(ctx, uid)
_, err = h.deviceService.GetDeviceByUID(ctx, uid)
if err != nil {
httpresponses.RespondWithError(w, http.StatusBadRequest, err.Error())
return
}

returnedMessages, err := h.service.GetMessagesByUID(ctx, uid, params.Offset, params.Limit)
returnedMessages, err := h.service.GetMessagesByUID(ctx, uid, offset, limit)
if err != nil {
httpresponses.RespondWithError(w, http.StatusInternalServerError, err.Error())
return
Expand All @@ -128,19 +144,14 @@ func (h *MessageHandler) GetDeviceMessagesByUID(w http.ResponseWriter, r *http.R
}

func (h *MessageHandler) GetAllMessages(w http.ResponseWriter, r *http.Request) {
params := GetMessagesRequest{}

decoder := json.NewDecoder(r.Body)
if err := decoder.Decode(&params); err != nil {
httpresponses.RespondWithError(w, http.StatusBadRequest, fmt.Sprintf("Request body could not be decoded as JSON: %v", err))
return
}
if params.Limit == 0 {
httpresponses.RespondWithError(w, http.StatusBadRequest, "Limit field is required")
offset, limit, err := parsePagination(r)
if err != nil {
httpresponses.RespondWithError(w, http.StatusBadRequest, "Invalid offset or limit query parameter")
return
}

ctx := r.Context()
returnedMessages, err := h.service.GetAllMessages(ctx, params.Offset, params.Limit)
returnedMessages, err := h.service.GetAllMessages(ctx, offset, limit)
if err != nil {
httpresponses.RespondWithError(w, http.StatusInternalServerError, err.Error())
return
Expand Down
10 changes: 0 additions & 10 deletions internal/messages/api/requests.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,3 @@ type CreateMessageRequest struct {
EventType string `json:"event_type"`
UID string `json:"uid"`
}

type GetMessageByIDRequest struct {
ID string `json:"id"`
EventType string `json:"event_type"`
}

type GetMessagesRequest struct {
Offset uint32 `json:"offset"`
Limit uint32 `json:"limit"`
}
Loading