A lightweight REST API built with Go standard library, featuring CRUD operations, JSON file persistence, and full test coverage.
- RESTful API with full CRUD operations
- Thread-safe in-memory storage with JSON persistence
- Built with Go standard library (minimal dependencies)
- Comprehensive unit tests
- Docker containerization with multi-stage builds
- Automatic ID generation and timestamp management
.
├── main.go # HTTP server and routing
├── handlers/
│ └── item_handler.go # CRUD endpoint handlers
├── models/
│ └── item.go # Data model
├── storage/
│ ├── storage.go # Storage implementation
│ └── storage_test.go # Unit tests
├── Dockerfile # Container configuration
└── data.json # Persistent data file (auto-generated)
- Go 1.24.5 or higher
- Docker (optional, for containerized deployment)
# Install dependencies
go mod download
# Run the service
go run main.go
# Or build and run the binary
go build -o service
./serviceThe server will start on http://localhost:8080
# Build the Docker image
docker build -t service:latest .
# Run the container
docker run -d -p 8080:8080 --name service service:latest
# View logs
docker logs service
# Stop the container
docker stop service
docker rm serviceTo persist data outside the container, mount a volume:
docker run -d -p 8080:8080 -v $(pwd)/data:/root --name service service:latestFor production deployment with automatic CI/CD:
- Set up GitHub Actions secrets (see DEPLOYMENT.md)
- Push to
mainbranch or trigger workflow manually - Service deploys automatically to Cloud Run
See DEPLOYMENT.md for complete setup instructions.
| Method | Endpoint | Description |
|---|---|---|
| POST | /items |
Create a new mushroom sighting |
| GET | /items |
Get all sightings |
| GET | /items/{id} |
Get sighting by ID |
| PUT | /items/{id} |
Update a sighting |
| DELETE | /items/{id} |
Delete a sighting |
The service uses a MushroomSighting model designed to match the UI's data structure:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"image": "data:image/jpeg;base64,...",
"mushroomName": "Boletus edulis",
"dateTime": "2025-11-09T19:24:00Z",
"location": "Pacific Northwest forest",
"count": 5,
"created_at": "2025-11-09T19:24:10Z",
"updated_at": "2025-11-09T19:24:10Z"
}| Field | Type | Required | Description |
|---|---|---|---|
id |
string | Auto-generated | Unique identifier (UUID) |
image |
string | Optional | Base64 encoded image of the mushroom |
mushroomName |
string | Optional | User's identification of the mushroom species |
dateTime |
timestamp | Required | When the mushroom was found (ISO 8601) |
location |
string | Required | Where the mushroom was found |
count |
integer | Required | Number of mushrooms found (minimum 1) |
created_at |
timestamp | Auto-generated | When the record was created |
updated_at |
timestamp | Auto-generated | When the record was last updated |
curl -X POST http://localhost:8080/items \
-H "Content-Type: application/json" \
-d '{
"mushroomName": "Boletus edulis",
"dateTime": "2025-11-09T14:30:00Z",
"location": "Pacific Northwest forest",
"count": 3
}'curl http://localhost:8080/itemscurl http://localhost:8080/items/550e8400-e29b-41d4-a716-446655440000curl -X PUT http://localhost:8080/items/550e8400-e29b-41d4-a716-446655440000 \
-H "Content-Type: application/json" \
-d '{
"mushroomName": "King Bolete",
"dateTime": "2025-11-09T14:30:00Z",
"location": "Pacific Northwest forest, near oak trees",
"count": 5
}'curl -X DELETE http://localhost:8080/items/550e8400-e29b-41d4-a716-446655440000go test ./...Data is automatically persisted to data.json in the working directory. The file is created on first write and loaded on startup.
The service currently uses a MushroomSighting model optimized for mushroom identification tracking. An Item type alias is maintained for backwards compatibility.
To further customize the data model:
- Update
models/item.gowith your struct definition - Ensure your struct has JSON tags for serialization
- Update validation in
handlers/item_handler.goif needed - The CRUD operations will automatically work with your new model
- Port: Default is
8080(configurable viaPORTenvironment variable for Cloud Run) - Data file: Default is
data.json(can be modified instorage/storage.go:27)
For production deployment to Google Cloud Run with automated CI/CD via GitHub Actions, see DEPLOYMENT.md.
Key features:
- Automatic deployment on push to
main - Container image storage in Google Artifact Registry
- Auto-scaling from 0 to 10 instances
- Pay-per-request pricing (~$0.50-$2/month for low traffic)
Note: Cloud Run is stateless. For production, consider migrating from data.json to:
- Cloud Storage (file-based)
- Cloud SQL (relational database)
- Firestore (NoSQL database)
See DEPLOYMENT.md for data persistence options.