Pet Platform is a Go/PostgreSQL API for pet adoption listings and lost-pet reports. It verifies Firebase Authentication Google ID tokens, synchronizes authenticated users with PostgreSQL, and derives the acting user from the verified token rather than trusting user IDs in request bodies.
flowchart LR
Client["Web or mobile client"] -->|HTTPS / JSON| Render["Render\nDocker web service"]
Render --> API["Go API\nchi router"]
API --> Public["Public handlers\nhealth, pets, stats"]
API --> Auth["Firebase ID-token\nverification"]
Auth --> Private["Authenticated handlers\nusers, pets, comments, applications"]
Public --> DB[("PostgreSQL\nSupabase or managed DB")]
Private --> DB
API --> Migrations["SQL migrations\nrun at startup"]
Auth --> Google["Google tokeninfo API"]
The API exposes public read endpoints and protects write operations with Firebase ID-token authentication. Database migrations are applied at startup unless AUTO_MIGRATE=false.
The service is configured for Render with the Blueprint in render.yaml.
- Service:
pet-platform-api - Live API: https://pet-platform-api.onrender.com
- Health check: https://pet-platform-api.onrender.com/health
Render's free service may take a few seconds to wake up after a period of inactivity.
Requirements: Go 1.23 and PostgreSQL.
cp .env.example .env
set -a; source .env; set +a
go run ./cmd/serverThe server listens on http://localhost:8080 by default.
| Method | Path | Description |
|---|---|---|
| GET | /health |
Database-backed health check |
| GET | /api/me |
Synchronize and return the authenticated user |
| GET, POST | /api/pets |
List or create pet listings |
| GET | /api/pets/{id} |
Return a pet listing and its comments |
| PATCH | /api/pets/{id}/status |
Mark an owned lost-pet report as found or closed |
| POST, DELETE | /api/pets/{id}/favorites |
Add or remove a favorite |
| GET | /api/users/{id}/favorites |
List a user's favorites |
| POST | /api/pets/{id}/comments |
Create a comment |
| POST | /api/pets/{id}/applications |
Apply for an adoption listing |
| GET | /api/users/{id}/applications?role=applicant|owner |
List adoption applications |
| PATCH | /api/applications/{id} |
Approve or reject an application |
| GET | /api/stats |
Return aggregate platform counts |
Pet listings can be filtered with type, status, species, location, q, page, and limit query parameters.
Set BASE_URL to the deployed service or override it for local development:
BASE_URL="${BASE_URL:-https://pet-platform-api.onrender.com}"curl --fail "$BASE_URL/health"curl --get "$BASE_URL/api/pets" \
--data-urlencode "type=lost" \
--data-urlencode "status=lost" \
--data-urlencode "location=Tokyo" \
--data-urlencode "limit=20"curl "$BASE_URL/api/pets/1"curl "$BASE_URL/api/stats"FIREBASE_ID_TOKEN must be a valid Firebase/Google ID token accepted by the configured GOOGLE_CLIENT_ID.
export FIREBASE_ID_TOKEN="<firebase-id-token>"
curl "$BASE_URL/api/me" \
-H "Authorization: Bearer $FIREBASE_ID_TOKEN"curl "$BASE_URL/api/pets" \
-X POST \
-H "Authorization: Bearer $FIREBASE_ID_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"listing_type": "lost",
"name": "Momo",
"species": "cat",
"breed": "Domestic Shorthair",
"sex": "female",
"age": 3,
"location": "Tokyo",
"description": "Last seen near the station.",
"image_url": "https://example.com/momo.jpg"
}'curl "$BASE_URL/api/pets/1/comments" \
-X POST \
-H "Authorization: Bearer $FIREBASE_ID_TOKEN" \
-H "Content-Type: application/json" \
-d '{"body":"I saw this pet near the park."}'go test ./...| Variable | Purpose |
|---|---|
PORT |
HTTP listen port; defaults to 8080 |
DATABASE_URL |
PostgreSQL connection string |
ALLOWED_ORIGINS |
Comma-separated CORS origins |
AUTO_MIGRATE |
Apply SQL migrations at startup; defaults to true |
MIGRATIONS_DIR |
Migration directory; defaults to migrations |
GOOGLE_CLIENT_ID |
Accepted Google/Firebase audience |