Skip to content

Latest commit

 

History

History
338 lines (248 loc) · 7.05 KB

File metadata and controls

338 lines (248 loc) · 7.05 KB

Getting Started with host-http

This guide will help you get started with host-http, from installation to building your first web API.

Prerequisites

  • Go 1.24 or later
  • Basic understanding of Go and HTTP concepts

Installation

Create a new Go module and install host-http:

mkdir my-api-project
cd my-api-project
go mod init my-api-project
go get github.com/Bofry/host-http

Your First Application

Step 1: Create the Basic Structure

Create main.go:

package main

import (
    http "github.com/Bofry/host-http"
    "github.com/Bofry/host-http/response"
)

// Define your API structure
//go:generate gen-host-http-request
type RequestManager struct {
    *UserRequest      `url:"/users"`
    *HealthRequest    `url:"/health"`
}

// User API handler
type UserRequest struct{}

func (r *UserRequest) Get(w http.ResponseWriter, req *http.Request) {
    users := []map[string]interface{}{
        {"id": 1, "name": "John Doe", "email": "john@example.com"},
        {"id": 2, "name": "Jane Smith", "email": "jane@example.com"},
    }
    response.JSON.Success(w, users)
}

func (r *UserRequest) Post(w http.ResponseWriter, req *http.Request) {
    // In real applications, you would parse request body
    newUser := map[string]interface{}{
        "id": 3,
        "name": "New User",
        "email": "newuser@example.com",
    }
    response.JSON.Success(w, newUser)
}

// Health check handler
type HealthRequest struct{}

func (r *HealthRequest) Get(w http.ResponseWriter, req *http.Request) {
    response.JSON.Success(w, map[string]string{
        "status": "healthy",
        "version": "1.0.0",
    })
}

// Application struct
type App struct{}

func main() {
    app := &App{}
    
    http.Startup(app).
        Middlewares(
            http.UseRequestManager(&RequestManager{}),
            http.UseErrorHandler(func(w http.ResponseWriter, req *http.Request, err any) {
                response.JSON.Failure(w, err, http.StatusInternalServerError)
            }),
        ).
        Run()
}

Step 2: Run Your Application

go run main.go

You should see output similar to:

2025/09/07 23:04:17 [host-http] % Notice: Server listening on address :8080

Step 3: Test Your API

Test the endpoints:

# Get users
curl http://localhost:8080/users

# Create a user (POST)
curl -X POST http://localhost:8080/users

# Health check
curl http://localhost:8080/health

Configuration

host-http provides sensible defaults to get you started quickly.

Default Settings

The framework automatically configures:

  • Listen Address: :8080 - Server listens on port 8080 by default
  • Version: 1.0.0 - Default application version
  • Compression: Disabled by default

Environment Variables

Override defaults using environment variables:

# Override port only
HTTP_PORT=3000 go run main.go

# Override full listen address
HTTP_LISTEN_ADDRESS=localhost:9090 go run main.go

Custom Configuration

For more control, define your own configuration structure:

package main

import http "github.com/Bofry/host-http"

type Config struct {
    ListenAddress  string `yaml:"ListenAddress"`
    EnableCompress bool   `yaml:"EnableCompress"`
    ServerName     string `yaml:"ServerName"`
}

type App struct {
    Host            *http.Host       `host:""`
    Config          *Config          `config:""`
    ServiceProvider *ServiceProvider `serviceProvider:""`
}

type ServiceProvider struct{}

func main() {
    app := &App{
        Config: &Config{
            ListenAddress: ":3000",
            EnableCompress: true,
            ServerName: "MyAPI",
        },
    }
    
    http.Startup(app).
        Middlewares(
            http.UseRequestManager(&RequestManager{}),
        ).
        Run()
}

Loading Configuration from Files

// config.yaml
ListenAddress: ":8080"
EnableCompress: true
ServerName: "MyAPI"

The framework supports automatic configuration loading from YAML files when used with the Bofry configuration system.

Adding Middleware

CORS Support

http.Startup(app).
    Middlewares(
        http.UseRequestManager(&RequestManager{}),
        http.UseCorsHeader("Authorization", "Content-Type"), // Custom headers
        http.UseErrorHandler(errorHandler),
    ).
    Run()

Logging

type LoggingService struct{}

func (s *LoggingService) ConfigureLogger(logger interface{}) {
    // Configure your logger
}

func (s *LoggingService) CreateEventLog(ev http.EventEvidence) http.EventLog {
    // Return your event log implementation
    return &MyEventLog{}
}

// Add to middleware chain
http.UseLogging(&LoggingService{})

HTTP Method Override

// Support X-Http-Method header for method override
http.UseXHttpMethodHeader()

Advanced Routing

Custom Method Binding

type RequestManager struct {
    *UserRequest `url:"/users" @BindMethod:"GET *FETCH"`  // Map FETCH method to GET
    *AdminRequest `url:"/admin" @ExpandEnv:"on"`          // Enable env expansion
}

Environment Variable Expansion

type RequestManager struct {
    *ApiRequest `url:"${API_PREFIX}/v1/data"` // Expands ${API_PREFIX}
}

Error Handling

Custom Error Handler

func errorHandler(w http.ResponseWriter, req *http.Request, err any) {
    switch e := err.(type) {
    case *failure.Failure:
        response.JSON.Failure(w, e, http.StatusBadRequest)
    case error:
        response.JSON.Failure(w, e.Error(), http.StatusInternalServerError)
    default:
        response.JSON.Failure(w, "Internal server error", http.StatusInternalServerError)
    }
}

Using Failure Package

import "github.com/Bofry/host-http/response/failure"

func (r *UserRequest) Get(w http.ResponseWriter, req *http.Request) {
    userID := req.URL.Query().Get("id")
    if userID == "" {
        failure.ThrowFailureMessage(failure.INVALID_ARGUMENT, "User ID is required")
        return
    }

    // Process request...
    response.JSON.Success(w, user)
}

Advanced Configuration

Server Configuration

func main() {
    app := &App{}
    
    starter := http.Startup(app)
    
    // Configure host before running
    host := starter.Host()
    host.SetListenAddress(":9000")
    host.SetServerName("MyAPI")
    
    starter.
        Middlewares(/*...*/).
        Run()
}

Next Steps

Common Issues

Port Already in Use

If you see "address already in use" error, either:

  • Change the port: host.SetListenAddress(":9000")
  • Stop the process using the port

Import Issues

Make sure you're using the correct import alias:

import http "github.com/Bofry/host-http"

Method Not Found

Ensure your request methods follow the naming convention:

  • Get for GET requests
  • Post for POST requests
  • Put for PUT requests
  • Delete for DELETE requests