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 developmentgolangci-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.