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-Key
header - âś… 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
.env
file 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 task
View all available tasks:
task --list
# or simply
task
Common 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 dev
The 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 docker
The 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 clean
Run 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/server
Generate 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 configure
Make 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 production
View function logs:
serverless logs -f api --tail
# or using Task
task logs
Remove the deployed service:
serverless remove --stage production
# or using Task
STAGE=production serverless remove
Health 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/endpoint
Error 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@latest
This installs:
air
- Hot reload for developmentgolangci-lint
- Linting tool
Start development server with hot reload:
task dev
Run code checks:
# Format code
task fmt
# Run linter (if installed)
task lint
# Run default task (format, test, build)
task default
Clean 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
gofmt
for 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_KEY
environment variable is set - Check that the
X-API-Key
header 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.