Implement client and server

This commit is contained in:
Micheal Wilkinson
2026-03-18 00:32:14 +00:00
parent 922b136c72
commit bc291a6941
3 changed files with 273 additions and 11 deletions

View File

@@ -1,34 +1,40 @@
package server
import (
"encoding/json"
"fmt"
"log"
"net/http"
"strconv"
"time"
"git.hrafn.xyz/aether/notes/internal/repository"
)
type Server struct {
httpServer *http.Server
noteRepo repository.NoteRepository
noteRepo *repository.NoteRepository
logger *log.Logger
}
func GetServer(repo repository.NoteRepository) Server {
func GetServer(repo *repository.NoteRepository, logger *log.Logger) Server {
mux := http.NewServeMux()
server := Server{
httpServer: &http.Server{Handler: mux},
httpServer: &http.Server{Handler: loggingMiddleware(mux, logger)},
noteRepo: repo,
logger: logger,
}
mux.HandleFunc("GET /notes", server.getNotes)
mux.HandleFunc("POST /notes", server.createNote)
mux.HandleFunc("GET /notes/{id}", server.getNoteByID)
mux.HandleFunc("PUT /notes/{id}", server.updateNoteByID)
mux.HandleFunc("DELETE /notes/{id}", server.deleteNoteByID)
mux.HandleFunc("GET /note/{id}", server.getNoteByID)
mux.HandleFunc("PUT /note/{id}", server.updateNoteByID)
mux.HandleFunc("DELETE /note/{id}", server.deleteNoteByID)
return server
}
func (s *Server) Start(addr string) error {
s.httpServer.Addr = addr
s.logger.Printf("Starting server on %s", addr)
return s.httpServer.ListenAndServe()
}
@@ -36,9 +42,31 @@ func (s *Server) Stop() error {
return s.httpServer.Close()
}
func loggingMiddleware(next http.Handler, logger *log.Logger) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
wrapped := &responseWriter{ResponseWriter: w, statusCode: http.StatusOK}
next.ServeHTTP(wrapped, r)
duration := time.Since(start)
logger.Printf("%s %s - %d (%dms)", r.Method, r.RequestURI, wrapped.statusCode, duration.Milliseconds())
})
}
type responseWriter struct {
http.ResponseWriter
statusCode int
}
func (rw *responseWriter) WriteHeader(code int) {
rw.statusCode = code
rw.ResponseWriter.WriteHeader(code)
}
func (s *Server) getJsonResponse(w http.ResponseWriter, data any) {
w.Header().Set("Content-Type", "application/json")
// Encode data to JSON and write to response
if err := json.NewEncoder(w).Encode(data); err != nil {
s.logger.Printf("failed to encode response: %v", err)
}
}
func (s *Server) getErrorResponse(w http.ResponseWriter, err error) {
@@ -58,7 +86,10 @@ func (s *Server) createNote(w http.ResponseWriter, r *http.Request) {
note := struct {
Content string `json:"content"`
}{}
// Decode JSON body into note struct
if err := json.NewDecoder(r.Body).Decode(&note); err != nil {
http.Error(w, "invalid request body", http.StatusBadRequest)
return
}
createdNote, err := s.noteRepo.CreateNote(r.Context(), note.Content)
if err != nil {
s.getErrorResponse(w, err)
@@ -92,7 +123,10 @@ func (s *Server) updateNoteByID(w http.ResponseWriter, r *http.Request) {
note := struct {
Content string `json:"content"`
}{}
// Decode JSON body into note struct
if err := json.NewDecoder(r.Body).Decode(&note); err != nil {
http.Error(w, "invalid request body", http.StatusBadRequest)
return
}
updatedNote, err := s.noteRepo.UpdateNote(r.Context(), id, note.Content)
if err != nil {
s.getErrorResponse(w, err)