go-faker/api/handlers.go
selamanapps 4ff98a40d4 feat: initial go-faker - Ethiopian fake data generator
- High-performance batch data generation (~150k records/sec)
- Seeded randomness for reproducible load tests
- Rich Ethiopian data: names, phones (+251), cities, regions
- Four data types: person, address, product, analytics
- Three modes: CLI, Go library, HTTP API
- Project skill available in .skills/go-faker/SKILL.md
2026-05-02 02:59:43 +03:00

100 lines
No EOL
2.3 KiB
Go

package api
import (
"encoding/json"
"net/http"
"time"
"go-faker/generator"
"go-faker/types"
)
type Handler struct {
faker *generator.Faker
}
func NewHandler(seed string) *Handler {
return &Handler{
faker: generator.New(seed),
}
}
func (h *Handler) Generate(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
var req types.GenerateRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "Invalid request body: "+err.Error(), http.StatusBadRequest)
return
}
defer r.Body.Close()
if req.Count <= 0 || req.Count > 100000 {
http.Error(w, "Count must be between 1 and 100000", http.StatusBadRequest)
return
}
if req.Seed == "" {
req.Seed = time.Now().UTC().Format(time.RFC3339Nano)
}
faker := generator.New(req.Seed)
validFields, ok := types.ValidFields[req.Type]
if !ok {
http.Error(w, "Invalid data type", http.StatusBadRequest)
return
}
if len(req.Fields) == 0 {
req.Fields = validFields
}
fieldSet := make(map[string]bool)
for _, f := range validFields {
fieldSet[f] = true
}
for _, f := range req.Fields {
if !fieldSet[f] {
http.Error(w, "Invalid field: "+f, http.StatusBadRequest)
return
}
}
data := faker.GenerateBatch(req.Count, req.Type, req.Fields)
response := types.GenerateResponse{
Data: data,
Format: "json",
Meta: types.ResponseMeta{
Count: req.Count,
Seed: req.Seed,
GeneratedAt: time.Now().UTC().Format(time.RFC3339),
},
}
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Access-Control-Allow-Origin", "*")
json.NewEncoder(w).Encode(response)
}
func (h *Handler) Health(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(map[string]string{"status": "ok"})
}
func (h *Handler) Fields(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Access-Control-Allow-Origin", "*")
json.NewEncoder(w).Encode(types.ValidFields)
}
func (h *Handler) RegisterRoutes(mux *http.ServeMux) {
mux.HandleFunc("/generate", h.Generate)
mux.HandleFunc("/fields", h.Fields)
mux.HandleFunc("/health", h.Health)
}