fasthttp

package
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Apr 14, 2025 License: MIT Imports: 19 Imported by: 0

README

FastHTTP Implementation Guide for MedaHTTP

This guide explains how to use the FastHTTP implementation of the MedaHTTP framework. The FastHTTP implementation provides high-performance HTTP server capabilities while maintaining compatibility with the MedaHTTP interface.

Table of Contents

Installation

To use the FastHTTP implementation, you need to have the required dependencies:

go get github.com/valyala/fasthttp
go get github.com/fasthttp/router
go get github.com/fasthttp/websocket

Basic Usage

Here's a basic example of how to create and start a FastHTTP server:

package main

import (
    "log"
    "github.com/medatechnology/simplehttp"
    "github.com/medatechnology/simplehttp/framework/fasthttp"
)

func main() {
    // Load configuration
    config := simplehttp.LoadConfig()
    
    // Create new FastHTTP server
    server := fasthttp.NewServer(config)
    
    // Define routes
    server.GET("/", func(c simplehttp.MedaContext) error {
        return c.String(200, "Hello, World!")
    })
    
    // Start server
    if err := server.Start(":8080"); err != nil {
        log.Fatal(err)
    }
}

Configuration

The FastHTTP implementation uses the standard MedaHTTP configuration. Here are the relevant environment variables:

MEDA_FRAMEWORK=fasthttp     # Specify FastHTTP as the framework
MEDA_PORT=8080             # Server port
MEDA_READ_TIMEOUT=30       # Read timeout in seconds
MEDA_WRITE_TIMEOUT=30      # Write timeout in seconds
MEDA_DEBUG=true           # Enable debug mode

Custom configuration example:

config := &simplehttp.Config{
    Framework:      "fasthttp",
    Port:           "8080",
    ReadTimeout:    time.Second * 30,
    WriteTimeout:   time.Second * 30,
    MaxRequestSize: 32 << 20, // 32MB
    Debug:          true,
}

Routing

The FastHTTP implementation supports all standard HTTP methods and route grouping:

// Basic routing
server.GET("/users", handleUsers)
server.POST("/users", createUser)
server.PUT("/users/:id", updateUser)
server.DELETE("/users/:id", deleteUser)

// Route grouping
api := server.Group("/api")
{
    v1 := api.Group("/v1")
    {
        v1.GET("/users", handleUsersV1)
        v1.POST("/users", createUserV1)
    }
}
Route Parameters

Access route parameters using the context:

server.GET("/users/:id", func(c simplehttp.MedaContext) error {
    id := c.GetParam("id")
    return c.JSON(200, map[string]string{"id": id})
})

Middleware

Adding middleware to your FastHTTP server:

// Global middleware
server.Use(simplehttp.LoggerMiddleware(logger))
server.Use(simplehttp.RequestID())

// Group middleware
api := server.Group("/api")
api.Use(simplehttp.BasicAuth("username", "password"))

// Route-specific middleware
server.GET("/protected", handler, simplehttp.BasicAuth("user", "pass"))

Built-in middleware examples:

// Timeout middleware
server.Use(simplehttp.Timeout(5 * time.Second))

// CORS middleware
corsConfig := &simplehttp.CORSConfig{
    AllowOrigins: []string{"*"},
    AllowMethods: []string{"GET", "POST", "PUT", "DELETE"},
    AllowHeaders: []string{"Origin", "Content-Type"},
}
server.Use(simplehttp.CORS(corsConfig))

// Rate limiter
rateLimitConfig := simplehttp.RateLimitConfig{
    RequestsPerSecond: 10,
    BurstSize:        20,
}
server.Use(simplehttp.RateLimiter(rateLimitConfig))

Context Usage

The FastHTTP context implementation provides access to request and response functionality:

server.POST("/api/data", func(c simplehttp.MedaContext) error {
    // Get request headers
    headers := c.GetHeaders()
    
    // Get query parameters
    query := c.GetQueryParam("filter")
    
    // Get request body
    var data map[string]interface{}
    if err := c.BindJSON(&data); err != nil {
        return err
    }
    
    // Send JSON response
    return c.JSON(200, map[string]interface{}{
        "status": "success",
        "data": data,
    })
})

Static Files

Serving static files with FastHTTP:

// Serve directory
server.Static("/assets", "./public")

// Serve single file
server.StaticFile("/favicon.ico", "./public/favicon.ico")

WebSocket Support

Implementing WebSocket endpoints:

server.WebSocket("/ws", func(ws simplehttp.MedaWebsocket) error {
    for {
        var msg map[string]interface{}
        if err := ws.ReadJSON(&msg); err != nil {
            return err
        }
        
        // Echo the message back
        if err := ws.WriteJSON(msg); err != nil {
            return err
        }
    }
})

Examples

Complete API Server Example
package main

import (
    "log"
    "time"
    
    "github.com/medatechnology/simplehttp"
    "github.com/medatechnology/simplehttp/framework/fasthttp"
)

type User struct {
    ID   string `json:"id"`
    Name string `json:"name"`
}

func main() {
    // Load configuration
    config := simplehttp.LoadConfig()
    
    // Create server
    server := fasthttp.NewServer(config)
    
    // Add middleware
    server.Use(simplehttp.LoggerMiddleware(simplehttp.NewDefaultLogger()))
    server.Use(simplehttp.RequestID())
    
    // API routes
    api := server.Group("/api")
    {
        api.Use(simplehttp.Timeout(5 * time.Second))
        
        // Users endpoints
        users := api.Group("/users")
        {
            users.GET("", listUsers)
            users.POST("", createUser)
            users.GET("/:id", getUser)
            users.PUT("/:id", updateUser)
            users.DELETE("/:id", deleteUser)
        }
    }
    
    // Start server
    if err := server.Start(config.Port); err != nil {
        log.Fatal(err)
    }
}

func listUsers(c simplehttp.MedaContext) error {
    users := []User{
        {ID: "1", Name: "John"},
        {ID: "2", Name: "Jane"},
    }
    return c.JSON(200, users)
}

func createUser(c simplehttp.MedaContext) error {
    var user User
    if err := c.BindJSON(&user); err != nil {
        return err
    }
    return c.JSON(201, user)
}

func getUser(c simplehttp.MedaContext) error {
    id := c.GetParam("id")
    user := User{ID: id, Name: "John Doe"}
    return c.JSON(200, user)
}

func updateUser(c simplehttp.MedaContext) error {
    var user User
    if err := c.BindJSON(&user); err != nil {
        return err
    }
    return c.JSON(200, user)
}

func deleteUser(c simplehttp.MedaContext) error {
    return c.JSON(204, nil)
}
File Upload Example
func handleFileUpload(c simplehttp.MedaContext) error {
    file, err := c.GetFile("file")
    if err != nil {
        return err
    }
    
    // Save the file
    dst := fmt.Sprintf("./uploads/%s", file.Filename)
    if err := c.SaveFile(file, dst); err != nil {
        return err
    }
    
    return c.JSON(200, map[string]string{
        "message": "File uploaded successfully",
        "path":    dst,
    })
}

Performance Considerations

The FastHTTP implementation is designed for high performance. Here are some tips to maximize performance:

  1. Use appropriate buffer sizes for your use case
  2. Enable compression only when needed
  3. Set reasonable timeouts
  4. Use connection pooling when making outbound requests
  5. Monitor memory usage with large file uploads

Error Handling

The FastHTTP implementation includes built-in error handling:

func handler(c simplehttp.MedaContext) error {
    // Return MedaError for structured error responses
    if someError {
        return simplehttp.NewError(400, "Bad Request", details)
    }
    
    // Regular errors are automatically handled
    return errors.New("something went wrong")
}

Graceful Shutdown

Implementing graceful shutdown:

func main() {
    server := fasthttp.NewServer(config)
    
    // Setup routes...
    
    // Start server in goroutine
    go func() {
        if err := server.Start(":8080"); err != nil {
            log.Printf("Server error: %v\n", err)
        }
    }()
    
    // Wait for interrupt signal
    quit := make(chan os.Signal, 1)
    signal.Notify(quit, os.Interrupt)
    <-quit
    
    // Graceful shutdown
    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)
    }
}

For more information and updates, please visit the project's GitHub repository.

Documentation

Overview

framework/fasthttp/adapter.go

framework/fasthttp/context.go

framework/fasthttp/server.go

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Adapter

Adapter converts MedaHandlerFunc to fasthttp.RequestHandler

func MiddlewareAdapter

func MiddlewareAdapter(middleware simplehttp.MedaMiddlewareFunc) func(fasthttp.RequestHandler) fasthttp.RequestHandler

MiddlewareAdapter converts MedaMiddleware to fasthttp middleware

func URIString2URL

func URIString2URL(uristring string) *url.URL

Convert fasthttp URI to net/url skipping the error!

Types

type FHContext

type FHContext struct {
	// contains filtered or unexported fields
}

func NewContext

func NewContext(ctx *fasthttp.RequestCtx) *FHContext

func (*FHContext) Bind

func (c *FHContext) Bind(v interface{}) error

Basic binding that supports query params, form data, and JSON body

func (*FHContext) BindForm

func (c *FHContext) BindForm(v interface{}) error

Form-specific binding with optimized map allocation

func (*FHContext) BindJSON

func (c *FHContext) BindJSON(v interface{}) error

JSON-specific binding with memory optimization. This is only to get payload from Request Body!

func (*FHContext) Context

func (c *FHContext) Context() context.Context

func (*FHContext) Get

func (c *FHContext) Get(key string) interface{}

func (*FHContext) GetBody

func (c *FHContext) GetBody() []byte

func (*FHContext) GetFile

func (c *FHContext) GetFile(fieldName string) (*multipart.FileHeader, error)

func (*FHContext) GetHeader

func (c *FHContext) GetHeader(key string) string

check for both request and response header

func (*FHContext) GetHeaders

func (c *FHContext) GetHeaders() *simplehttp.RequestHeader

func (*FHContext) GetMethod

func (c *FHContext) GetMethod() string

func (*FHContext) GetPath

func (c *FHContext) GetPath() string

func (*FHContext) GetQueryParam

func (c *FHContext) GetQueryParam(key string) string

func (*FHContext) GetQueryParams

func (c *FHContext) GetQueryParams() map[string][]string

func (*FHContext) JSON

func (c *FHContext) JSON(code int, data interface{}) error

func (*FHContext) Request

func (c *FHContext) Request() *http.Request

func (*FHContext) Response

func (c *FHContext) Response() http.ResponseWriter

func (*FHContext) SaveFile

func (c *FHContext) SaveFile(file *multipart.FileHeader, dst string) error

func (*FHContext) SendFile

func (c *FHContext) SendFile(filepath string, attachment bool) error

func (*FHContext) Set

func (c *FHContext) Set(key string, value interface{})

func (*FHContext) SetContext

func (c *FHContext) SetContext(ctx context.Context)

func (*FHContext) SetHeader

func (c *FHContext) SetHeader(key, value string)

func (*FHContext) SetRequestHeader

func (c *FHContext) SetRequestHeader(key, value string)

func (*FHContext) SetResponseHeader

func (c *FHContext) SetResponseHeader(key, value string)

func (*FHContext) Stream

func (c *FHContext) Stream(code int, contentType string, reader io.Reader) error

func (*FHContext) String

func (c *FHContext) String(code int, data string) error

func (*FHContext) Upgrade

func (c *FHContext) Upgrade() (simplehttp.MedaWebsocket, error)

type RouterGroup

type RouterGroup struct {
	// contains filtered or unexported fields
}

RouterGroup implements group routing

func (*RouterGroup) DELETE

func (g *RouterGroup) DELETE(path string, handler simplehttp.MedaHandlerFunc)

func (*RouterGroup) GET

func (g *RouterGroup) GET(path string, handler simplehttp.MedaHandlerFunc)

func (*RouterGroup) Group

func (g *RouterGroup) Group(prefix string) simplehttp.MedaRouter

func (*RouterGroup) HEAD

func (g *RouterGroup) HEAD(path string, handler simplehttp.MedaHandlerFunc)

func (*RouterGroup) OPTIONS

func (g *RouterGroup) OPTIONS(path string, handler simplehttp.MedaHandlerFunc)

func (*RouterGroup) PATCH

func (g *RouterGroup) PATCH(path string, handler simplehttp.MedaHandlerFunc)

func (*RouterGroup) POST

func (g *RouterGroup) POST(path string, handler simplehttp.MedaHandlerFunc)

func (*RouterGroup) PUT

func (g *RouterGroup) PUT(path string, handler simplehttp.MedaHandlerFunc)

func (*RouterGroup) Static

func (g *RouterGroup) Static(prefix, root string)

func (*RouterGroup) StaticFile

func (g *RouterGroup) StaticFile(path, filepath string)

func (*RouterGroup) Use

func (g *RouterGroup) Use(middleware ...simplehttp.MedaMiddleware)

func (*RouterGroup) WebSocket

func (g *RouterGroup) WebSocket(path string, handler func(simplehttp.MedaWebsocket) error)

type Server

type Server struct {
	// contains filtered or unexported fields
}

func NewServer

func NewServer(config *simplehttp.Config) *Server

func (*Server) DELETE

func (s *Server) DELETE(path string, handler simplehttp.MedaHandlerFunc)

func (*Server) GET

func (s *Server) GET(path string, handler simplehttp.MedaHandlerFunc)

func (*Server) Group

func (s *Server) Group(prefix string) simplehttp.MedaRouter

func (*Server) HEAD

func (s *Server) HEAD(path string, handler simplehttp.MedaHandlerFunc)

func (*Server) OPTIONS

func (s *Server) OPTIONS(path string, handler simplehttp.MedaHandlerFunc)

func (*Server) PATCH

func (s *Server) PATCH(path string, handler simplehttp.MedaHandlerFunc)

func (*Server) POST

func (s *Server) POST(path string, handler simplehttp.MedaHandlerFunc)

func (*Server) PUT

func (s *Server) PUT(path string, handler simplehttp.MedaHandlerFunc)

func (*Server) Shutdown

func (s *Server) Shutdown(ctx context.Context) error

func (*Server) Start

func (s *Server) Start(address string) error

func (*Server) Static

func (s *Server) Static(prefix, root string)

func (*Server) StaticFile

func (s *Server) StaticFile(path, filepath string)

func (*Server) Use

func (s *Server) Use(middleware ...simplehttp.MedaMiddleware)

func (*Server) WebSocket

func (s *Server) WebSocket(path string, handler func(simplehttp.MedaWebsocket) error)

Jump to

Keyboard shortcuts

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