A minimal Golang HTTP API built with the standard library, featuring API key authentication and designed for serverless deployment on AWS Lambda.
- âś… Pure Go implementation using only net/http(no external frameworks)
- âś… API key authentication via X-API-Keyheader
- âś… Health check endpoint at /health
- âś… Graceful shutdown support
- âś… Request logging middleware
- âś… Comprehensive unit tests
- âś… AWS Lambda deployment ready with Serverless Framework
- âś… Dual deployment: Run locally as HTTP server or deploy to AWS Lambda
/
├── cmd/
│   ├── api/
│   │   └── main.go           # Local server entry point
│   └── lambda/
│       └── main.go           # AWS Lambda entry point
├── internal/
│   ├── handlers/
│   │   ├── health.go         # Health check handler
│   │   └── handlers_test.go  # Handler tests
│   ├── middleware/
│   │   ├── auth.go           # Authentication middleware
│   │   └── auth_test.go      # Middleware tests
│   └── server/
│       ├── server.go         # Server setup and configuration
│       └── server_test.go    # Server tests
├── serverless.yml            # Serverless Framework configuration
├── Taskfile.yml              # Task runner configuration
├── .air.toml                 # Hot reload configuration
├── Dockerfile                # Docker configuration
├── .gitignore                # Git ignore file
├── go.mod                    # Go module file
└── README.md                 # This file
- Go 1.21 or higher
- Git
- Task - Task runner (recommended)
- (Optional) Serverless Framework for deployment
- (Optional) AWS CLI configured with appropriate credentials
- (Optional) Docker for containerized deployment
- Clone the repository:
git clone https://github.com/nicobistolfi/go-lambda-api.git
cd go-lambda-api- Install dependencies:
go mod download
# or using Task
task mod- Create a .envfile from the example:
cp .env.example .env
# Edit .env and set your API_KEY- Install Task runner (if not already installed):
# macOS
brew install go-task/tap/go-task
# Linux
sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d
# Windows (using Scoop)
scoop install taskView all available tasks:
task --list
# or simply
taskCommon operations:
# Run the server locally
task run
# Run tests
task test
# Run tests with coverage
task test-coverage
# Build the binary
task build
# Format code
task fmt
# Start development server with hot reload
task devThe application uses the following environment variables:
| Variable | Description | Default | Required | 
|---|---|---|---|
| API_KEY | API key for authentication | - | Yes | 
| PORT | Port to run the server on | 8080 | No | 
# Run with default dev API key
task run
# Run with custom API key
API_KEY="your-secret-api-key" task run
# Run on custom port
PORT=3000 task run- Set the required environment variables:
export API_KEY="your-secret-api-key"
export PORT="8080"  # Optional, defaults to 8080- Run the server:
go run cmd/api/main.go# Build and run in Docker
API_KEY="your-secret-api-key" task dockerThe server will start on http://localhost:8080 (or the port specified).
Health check (no authentication required):
curl http://localhost:8080/health
# or using Task
curl http://localhost:8080/health | jq .Expected response:
{"status":"ok"}With authentication (for future authenticated endpoints):
curl -H "X-API-Key: your-secret-api-key" http://localhost:8080/some-endpoint
# or using Task with custom API key
API_KEY="your-secret-api-key" task run# Run all tests
task test
# Run tests with coverage
task test-coverage
# Run linter
task lint
# Clean build artifacts
task cleanRun all tests with coverage:
go test -v -cover ./...Run tests for a specific package:
go test -v ./internal/handlers
go test -v ./internal/middleware
go test -v ./internal/serverGenerate coverage report:
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out -o coverage.html- Install Serverless Framework:
npm install -g serverless- Install dependencies:
npm install- Configure AWS credentials:
aws configureMake sure you have a .env file with your API_KEY set, or pass it explicitly:
# Deploy using .env file
task deploy
# Or deploy with explicit API_KEY
API_KEY="your-api-key" task deploy
# Deploy to specific stage
STAGE=production task deploy
# View logs
task logs- Set your API key as an environment variable:
export API_KEY="your-production-api-key"- Deploy to AWS:
serverless deploy --stage production --region us-west-1- Deploy to a specific stage:
serverless deploy --stage dev
serverless deploy --stage staging
serverless deploy --stage productionView function logs:
serverless logs -f api --tail
# or using Task
task logsRemove the deployed service:
serverless remove --stage production
# or using Task
STAGE=production serverless removeHealth check endpoint that returns the service status.
Authentication: Not required
Response:
- Status: 200 OK
- Body: {"status": "ok"}
All endpoints (except /health) require API key authentication via the X-API-Key header.
Example:
curl -H "X-API-Key: your-api-key" https://your-api-url.com/endpointError Responses:
- 401 Unauthorized- Missing or invalid API key- {"error": "Missing API key"}
- {"error": "Invalid API key"}
- {"error": "API key not configured"}
 
Install development dependencies:
go install github.com/cosmtrek/air@latest
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latestThis installs:
- air- Hot reload for development
- golangci-lint- Linting tool
Start development server with hot reload:
task devRun code checks:
# Format code
task fmt
# Run linter (if installed)
task lint
# Run default task (format, test, build)
task defaultClean build artifacts:
task clean- Create a new handler in internal/handlers/
- Add authentication by wrapping with middleware.AuthMiddleware()
- Register the route in internal/server/server.go
- Write comprehensive tests
Example:
// In internal/server/server.go
mux.HandleFunc("/api/users", middleware.AuthMiddleware(handlers.UsersHandler))- Follow standard Go conventions
- Use gofmtfor formatting
- Keep functions small and focused
- Write tests for all new functionality
- Use meaningful variable and function names
- 
Server fails to start - Check if the port is already in use
- Ensure all environment variables are set correctly
 
- 
Authentication failures - Verify the API_KEYenvironment variable is set
- Check that the X-API-Keyheader matches exactly
 
- Verify the 
- 
Deployment issues - Ensure AWS credentials are configured
- Check Serverless Framework version compatibility
- Verify the Go version matches the Lambda runtime
 
- Fork the repository
- Create a feature branch (git checkout -b feature/amazing-feature)
- Commit your changes (git commit -m 'Add some amazing feature')
- Push to the branch (git push origin feature/amazing-feature)
- Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.