feat(tfstated): add json encoding and decoding helpers
This commit is contained in:
		
					parent
					
						
							
								2cdbc4e782
							
						
					
				
			
			
				commit
				
					
						d4a82f610c
					
				
			
		
					 3 changed files with 46 additions and 13 deletions
				
			
		cmd/tfstated
| 
						 | 
					@ -12,21 +12,20 @@ import (
 | 
				
			||||||
func handleGet(db *database.DB) http.Handler {
 | 
					func handleGet(db *database.DB) http.Handler {
 | 
				
			||||||
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 | 
						return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
		w.Header().Set("Cache-Control", "no-store, no-cache")
 | 
							w.Header().Set("Cache-Control", "no-store, no-cache")
 | 
				
			||||||
		w.Header().Set("Content-Type", "application/json")
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if r.URL.Path == "/" {
 | 
							if r.URL.Path == "/" {
 | 
				
			||||||
			w.WriteHeader(http.StatusBadRequest)
 | 
								_ = errorResponse(w, http.StatusBadRequest,
 | 
				
			||||||
			_, _ = w.Write([]byte("{\"msg\": \"No state path provided, cannot GET /\"}"))
 | 
									fmt.Errorf("no state path provided, cannot GET /"))
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if data, err := db.GetState(r.URL.Path); err != nil {
 | 
							if data, err := db.GetState(r.URL.Path); err != nil {
 | 
				
			||||||
			if errors.Is(err, sql.ErrNoRows) {
 | 
								if errors.Is(err, sql.ErrNoRows) {
 | 
				
			||||||
				w.WriteHeader(http.StatusNotFound)
 | 
									_ = errorResponse(w, http.StatusNotFound,
 | 
				
			||||||
 | 
										fmt.Errorf("state path not found: %s", r.URL.Path))
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				w.WriteHeader(http.StatusInternalServerError)
 | 
									_ = errorResponse(w, http.StatusInternalServerError, err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			_, _ = w.Write([]byte(fmt.Sprintf("{\"msg\": \"%+v\"}", err)))
 | 
					 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			w.WriteHeader(http.StatusOK)
 | 
								w.WriteHeader(http.StatusOK)
 | 
				
			||||||
			_, _ = w.Write(data)
 | 
								_, _ = w.Write(data)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										36
									
								
								cmd/tfstated/helpers.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								cmd/tfstated/helpers.go
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,36 @@
 | 
				
			||||||
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"log/slog"
 | 
				
			||||||
 | 
						"net/http"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func decode(r *http.Request, data any) error {
 | 
				
			||||||
 | 
						if err := json.NewDecoder(r.Body).Decode(&data); err != nil {
 | 
				
			||||||
 | 
							return fmt.Errorf("failed to decode json: %w", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func encode(w http.ResponseWriter, status int, data any) error {
 | 
				
			||||||
 | 
						w.Header().Set("Content-Type", "application/json")
 | 
				
			||||||
 | 
						w.WriteHeader(status)
 | 
				
			||||||
 | 
						if err := json.NewEncoder(w).Encode(data); err != nil {
 | 
				
			||||||
 | 
							slog.Error("failed to encode json", "err", err)
 | 
				
			||||||
 | 
							return fmt.Errorf("failed to encode json: %w", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func errorResponse(w http.ResponseWriter, status int, err error) error {
 | 
				
			||||||
 | 
						type errorResponse struct {
 | 
				
			||||||
 | 
							Msg    string `json:"msg"`
 | 
				
			||||||
 | 
							Status int    `json:"status"`
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return encode(w, status, &errorResponse{
 | 
				
			||||||
 | 
							Msg:    fmt.Sprintf("%+v", err),
 | 
				
			||||||
 | 
							Status: status,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -10,21 +10,19 @@ import (
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func handlePost(db *database.DB) http.Handler {
 | 
					func handlePost(db *database.DB) http.Handler {
 | 
				
			||||||
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 | 
						return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
		w.Header().Set("Content-Type", "application/json")
 | 
					 | 
				
			||||||
		if r.URL.Path == "/" {
 | 
							if r.URL.Path == "/" {
 | 
				
			||||||
			w.WriteHeader(http.StatusBadRequest)
 | 
								_ = errorResponse(w, http.StatusBadRequest,
 | 
				
			||||||
			_, _ = w.Write([]byte("{\"msg\": \"No state path provided, cannot POST /\"}"))
 | 
									fmt.Errorf("no state path provided, cannot POST /"),
 | 
				
			||||||
 | 
								)
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		data, err := io.ReadAll(r.Body)
 | 
							data, err := io.ReadAll(r.Body)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			w.WriteHeader(http.StatusBadRequest)
 | 
								_ = errorResponse(w, http.StatusBadRequest, err)
 | 
				
			||||||
			_, _ = w.Write([]byte(fmt.Sprintf("{\"msg\": \"failed to read request body: %+v\"}", err)))
 | 
					 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if err := db.SetState(r.URL.Path, data); err != nil {
 | 
							if err := db.SetState(r.URL.Path, data); err != nil {
 | 
				
			||||||
			w.WriteHeader(http.StatusInternalServerError)
 | 
								_ = errorResponse(w, http.StatusInternalServerError, err)
 | 
				
			||||||
			_, _ = w.Write([]byte(fmt.Sprintf("{\"msg\": \"%+v\"}", err)))
 | 
					 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			w.WriteHeader(http.StatusOK)
 | 
								w.WriteHeader(http.StatusOK)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue