A simple CRM-style API server for managing contacts and files. Available in both Go and Java implementations with identical API interfaces.
- Go: Located in
go/directory - Java: Located in
java/directory (Spring Boot)
Both implementations share the same SQLite database schema and provide identical REST API endpoints.
cd go
make seed # Seed the database with test data
make run # Start the serverOr without make:
cd go
go run ./cmd/server --seed
go run ./cmd/servercd java
make seed # Seed the database with test data
make run # Start the serverOr without make:
cd java
./mvnw spring-boot:run -Dspring-boot.run.arguments="--app.seed=true"
./mvnw spring-boot:runThe server runs on http://localhost:8080 by default.
All /api/* endpoints require a bearer token in the Authorization header:
curl -H "Authorization: Bearer [email protected]" http://localhost:8080/api/contactsThe token should be a valid email address. It serves as the user identifier.
| Method | Path | Description |
|---|---|---|
GET |
/health |
Health check (no auth required) |
| Method | Path | Description |
|---|---|---|
GET |
/api/contacts |
List contacts (paginated) |
GET |
/api/contacts/:id |
Get a contact |
POST |
/api/contacts |
Create a contact |
PUT |
/api/contacts/:id |
Update a contact |
DELETE |
/api/contacts/:id |
Delete a contact |
POST |
/api/contacts/import |
Bulk import contacts (JSON array, max 10k) |
GET |
/api/contacts/export |
Export all contacts as CSV |
| Method | Path | Description |
|---|---|---|
GET |
/api/files |
List files |
POST |
/api/files |
Upload a file (multipart form, max 100MB) |
GET |
/api/files/:id |
Download a file |
| Method | Path | Description |
|---|---|---|
GET |
/api/reports/activity |
Activity report (last 30 days by default) |
The /api/contacts endpoint uses cursor-based pagination. The response includes a next_page_token field when more results are available:
{
"contacts": [...],
"next_page_token": "eyJjcmVhdGVkX2F0Ijoi..."
}Pass the token as a query parameter to fetch the next page:
curl -H "Authorization: Bearer [email protected]" \
"http://localhost:8080/api/contacts?page_token=eyJjcmVhdGVkX2F0Ijoi..."# List contacts (first page)
curl -H "Authorization: Bearer [email protected]" \
http://localhost:8080/api/contacts?limit=10
# Create a contact
curl -X POST -H "Authorization: Bearer [email protected]" \
-H "Content-Type: application/json" \
-d '{"first_name":"Jane","last_name":"Doe","email":"[email protected]","phone":"555-1234","company":"Acme"}' \
http://localhost:8080/api/contacts
# Upload a file
curl -X POST -H "Authorization: Bearer [email protected]" \
-F "file=@/path/to/file.pdf" \
http://localhost:8080/api/files
# Bulk import
curl -X POST -H "Authorization: Bearer [email protected]" \
-H "Content-Type: application/json" \
-d '[{"first_name":"A","last_name":"B","email":"[email protected]","phone":"555","company":"X"}]' \
http://localhost:8080/api/contacts/import
# Export contacts
curl -H "Authorization: Bearer [email protected]" \
http://localhost:8080/api/contacts/export > contacts.csvcd go
make seed # Default: 10k contacts, 20 files
go run ./cmd/server --seed --contacts=50000 # Custom contact count
go run ./cmd/server --seed --files=100 # Custom file countcd java
make seed # Default: 10k contacts, 20 files
./mvnw spring-boot:run -Dspring-boot.run.arguments="--app.seed=true --contacts=50000" # Custom contact countTo reset the database:
cd go && make reset # Go
cd java && make reset # Javacd go
make bench| Flag | Default | Description |
|---|---|---|
--addr |
:8080 |
Server listen address |
--data |
data |
Data directory for database and files |
--seed |
false |
Seed database with test data |
--contacts |
10000 |
Number of contacts to seed |
--files |
20 |
Number of files to seed |
Configuration is in src/main/resources/application.properties:
| Property | Default | Description |
|---|---|---|
server.port |
8080 |
Server listen port |
app.data-dir |
data |
Data directory for database and files |
app.max-upload-size |
104857600 |
Max file upload size (100MB) |