example

command
v0.0.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 16, 2025 License: MIT Imports: 13 Imported by: 0

README

Usage example

package main

import (
	"context"
	"log"
	"net/http"
	"os"
	"os/signal"
	"time"

	"github.com/medatechnology/simplehttp"
	"github.com/medatechnology/simplehttp/framework/fiber"
)

// Define a simple User type for demonstration purposes
type User struct {
	ID   string `json:"id"`
	Name string `json:"name"`
}

// Handler functions
func getUsers(c simplehttp.Context) error {
	users := []User{
		{ID: "1", Name: "John Doe"},
		{ID: "2", Name: "Jane Smith"},
	}
	return c.JSON(http.StatusOK, users)
}

func getUserByID(c simplehttp.Context) error {
	id := c.GetQueryParam("id")
	if id == "" {
		return simplehttp.NewError(http.StatusBadRequest, "Missing ID parameter")
	}

	// In a real app, you would fetch the user from a database
	user := User{ID: id, Name: "Example User"}
	return c.JSON(http.StatusOK, user)
}

func createUser(c simplehttp.Context) error {
	var user User
	if err := c.BindJSON(&user); err != nil {
		return simplehttp.NewError(http.StatusBadRequest, "Invalid user data")
	}

	// In a real app, you would save the user to a database
	return c.JSON(http.StatusCreated, user)
}

func handleWebSocket(ws simplehttp.WebSocket) error {
	// Simple chat message type
	type Message struct {
		Type string `json:"type"`
		Text string `json:"text"`
	}

	for {
		// Read message from client
		msg := &Message{}
		if err := ws.ReadJSON(msg); err != nil {
			return err
		}

		// Echo the message back with a timestamp
		reply := &Message{
			Type: "reply",
			Text: "Echo: " + msg.Text + " (at " + time.Now().Format(time.RFC3339) + ")",
		}

		if err := ws.WriteJSON(reply); err != nil {
			return err
		}
	}
}

func main() {
	// Load configuration
	config := simplehttp.LoadConfig()
	config.Debug = true // Enable debug mode for verbose output

	// Create a server with the Fiber implementation
	server := fiber.NewServer(config)

	// Add global middleware
	server.Use(
		simplehttp.MiddlewareRequestID(),                             // Add unique request IDs
		simplehttp.MiddlewareLogger(simplehttp.NewDefaultLogger()),   // Log all requests
		simplehttp.MiddlewareTimeout(*config.ConfigTimeOut),          // Apply timeouts
		simplehttp.MiddlewareHeaderParser(),                          // Parse headers
	)

	// Security configuration
	securityConfig := simplehttp.SecurityConfig{
		FrameDeny:          true,
		ContentTypeNosniff: true,
		BrowserXssFilter:   true,
	}

	// Rate limiting configuration
	rateLimitConfig := simplehttp.RateLimitConfig{
		RequestsPerSecond: 10,
		BurstSize:         20,
		KeyFunc: func(c simplehttp.Context) string {
			headers := c.GetHeaders()
			return headers.RemoteIP // Rate limit by IP
		},
	}

	// CORS configuration
	corsConfig := &simplehttp.CORSConfig{
		AllowOrigins:     []string{"*"},
		AllowMethods:     []string{"GET", "POST", "PUT", "DELETE"},
		AllowHeaders:     []string{"Origin", "Content-Type", "Authorization"},
		AllowCredentials: false,
		MaxAge:           24 * time.Hour,
	}

	// Create API routes
	api := server.Group("/api")
	{
		// Add route-specific middleware
		api.Use(
			simplehttp.MiddlewareSecurity(securityConfig),
			simplehttp.MiddlewareRateLimiter(rateLimitConfig),
			simplehttp.MiddlewareCORS(corsConfig),
		)

		// User endpoints
		users := api.Group("/users")
		{
			users.GET("", getUsers)
			users.GET("/:id", getUserByID)
			users.POST("", createUser)
		}

		// Status endpoint
		api.GET("/status", func(c simplehttp.Context) error {
			headers := c.GetHeaders()
			return c.JSON(http.StatusOK, map[string]interface{}{
				"status":  "OK",
				"time":    time.Now().Format(time.RFC3339),
				"request": headers.RequestID,
			})
		})
	}

	// File handling example
	fileHandler := simplehttp.NewFileHandler("./uploads")
	fileHandler.MaxFileSize = 10 << 20 // 10MB
	fileHandler.AllowedTypes = []string{
		"image/jpeg",
		"image/png",
		"application/pdf",
	}

	files := server.Group("/files")
	{
		files.POST("/upload", fileHandler.HandleUpload())
		files.GET("/download/:filename", fileHandler.HandleDownload("./uploads/{{filename}}"))
	}

	// WebSocket example
	server.WebSocket("/ws/chat", handleWebSocket)

	// Start server in a goroutine
	go func() {
		log.Printf("Starting server on %s:%s", config.Hostname, config.Port)
		if err := server.Start(""); err != nil {
			log.Printf("Server error: %v", err)
		}
	}()

	// Wait for interrupt signal
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, os.Interrupt)
	<-quit

	log.Println("Shutting down server...")

	// Gracefully shutdown with a timeout
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	if err := server.Shutdown(ctx); err != nil {
		log.Fatal("Server forced to shutdown:", err)
	}

	log.Println("Server shutdown complete")
}

Documentation

Overview

examples/echo/main.go

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL