Microservice responsible for post management, feed generation, and social feed-related operations.
The Feed Service handles all post and feed-related functionality including:
- Post creation and management
- Feed generation with pagination
- Interest-based post discovery
- Post interest management
- Like/unlike functionality
API Gateway β Composite Service β Feed Service β Feed Database (Cloud SQL)
- Port: 8003
- Database: MySQL (Cloud SQL or local)
- Authentication: Trusts
x-firebase-uidheader from API Gateway - Deployment: Can run on Cloud Run or Compute Engine VM
- Python 3.9+
- MySQL 8.0+
- Firebase service account key
-
Install dependencies
pip install -r requirements.txt
-
Set up database
mysql -u root -p feed_db < ../DB-Service/initFeed.sql -
Configure environment variables Create a
.envfile:DB_HOST=127.0.0.1 DB_USER=root DB_PASS=your_password DB_NAME=feed_db FIREBASE_SERVICE_ACCOUNT_PATH=./serviceAccountKey.json
-
Add Firebase service account key
- Download from Firebase Console
- Place as
serviceAccountKey.jsonin service directory
-
Run the service
uvicorn main:app --host 0.0.0.0 --port 8003
| Variable | Description | Default | Required |
|---|---|---|---|
DB_HOST |
Database host address | 127.0.0.1 |
Yes |
DB_USER |
Database username | root |
Yes |
DB_PASS |
Database password | - | Yes |
DB_NAME |
Database name | feed_db |
Yes |
FIREBASE_SERVICE_ACCOUNT_PATH |
Path to Firebase service account JSON | ./serviceAccountKey.json |
No |
Get all posts with pagination and filtering
Query Parameters:
skip: Number of posts to skip (default: 0)limit: Number of posts to return (default: 10, max: 100)interest_id: Filter by interest IDcreated_by: Filter by creator user IDsearch: Search in title and body
Headers:
x-firebase-uid: Firebase user ID (injected by API Gateway)
Response:
{
"items": [
{
"post_id": 1,
"title": "My First Post",
"body": "This is my first post!",
"created_by": 1,
"created_at": "2024-01-01T00:00:00",
"likes_count": 5,
"interests": [
{"interest_id": 1, "interest_name": "Technology"}
],
"_links": {
"self": {"href": "/posts/1"},
"collection": {"href": "/posts"}
}
}
],
"total": 50,
"skip": 0,
"limit": 10
}ETag Support: Returns ETag header for caching
Get post by ID
Response:
{
"post_id": 1,
"title": "My First Post",
"body": "This is my first post!",
"created_by": 1,
"created_at": "2024-01-01T00:00:00",
"updated_at": "2024-01-01T00:00:00",
"likes_count": 5,
"interests": [...],
"_links": {...}
}Create a new post
Request Body:
{
"title": "My First Post",
"body": "This is my first post!",
"interest_ids": [1, 2, 3]
}Response:
201 Createdwith post data
Update a post (full update)
Request Body:
{
"title": "Updated Post Title",
"body": "Updated post body",
"interest_ids": [1, 2]
}ETag Support: Requires If-Match header for optimistic locking
Partially update a post
Request Body:
{
"title": "Updated Title"
}ETag Support: Requires If-Match header
Delete a post
ETag Support: Requires If-Match header
Get interests for a post
Add interests to a post
Request Body:
{
"interest_ids": [1, 2, 3]
}Remove interest from a post
Like a post
Response:
{
"post_id": 1,
"likes_count": 6,
"liked": true
}Unlike a post
Response:
{
"post_id": 1,
"likes_count": 5,
"liked": false
}Get personalized feed for current user
Query Parameters:
skip: Number of posts to skip (default: 0)limit: Number of posts to return (default: 10, max: 100)
Response: Returns posts from users the current user follows, ordered by creation date.
This service does not perform Firebase authentication directly. It trusts the x-firebase-uid header injected by the API Gateway middleware.
post_id(INT, PRIMARY KEY, AUTO_INCREMENT)title(VARCHAR)body(TEXT)created_by(INT, FOREIGN KEY to Users)created_at(TIMESTAMP)updated_at(TIMESTAMP)
post_id(INT, FOREIGN KEY)interest_id(INT, FOREIGN KEY)
post_id(INT, FOREIGN KEY)user_id(INT, FOREIGN KEY)created_at(TIMESTAMP)- PRIMARY KEY (post_id, user_id)
interest_id(INT, PRIMARY KEY)interest_name(VARCHAR, UNIQUE)
docker build -t feed-service .docker run -p 8003:8003 \
-e DB_HOST=your_db_host \
-e DB_USER=your_db_user \
-e DB_PASS=your_db_password \
-e DB_NAME=feed_db \
feed-serviceThe service can be deployed to Cloud Run with:
- VPC Connector for database access
- Private IP connection to Cloud SQL
- Environment variables configured via deployment script
The service can also run on a Compute Engine VM:
- Direct VPC connection to Cloud SQL
- Systemd service for auto-start
- No external IP required
See ../GCP_DEPLOYMENT_GUIDE.md for details.
curl http://localhost:8003/curl -H "x-firebase-uid: your-firebase-uid" \
http://localhost:8003/postscurl -X POST \
-H "x-firebase-uid: your-firebase-uid" \
-H "Content-Type: application/json" \
-d '{
"title": "Test Post",
"body": "Test post body",
"interest_ids": [1]
}' \
http://localhost:8003/postscurl -X POST \
-H "x-firebase-uid: your-firebase-uid" \
http://localhost:8003/posts/1/likeInteractive API documentation available at:
- Swagger UI:
http://localhost:8003/docs - ReDoc:
http://localhost:8003/redoc - OpenAPI JSON:
http://localhost:8003/openapi.json
The service returns standard HTTP status codes:
200 OK: Successful request201 Created: Post created400 Bad Request: Invalid request data401 Unauthorized: Missing or invalidx-firebase-uidheader404 Not Found: Post not found409 Conflict: ETag mismatch (optimistic locking)412 Precondition Failed: ETag required but not provided500 Internal Server Error: Server error
- HATEOAS: All responses include
_linksfor navigation - ETag Support: Optimistic locking for updates
- Pagination: Skip/limit for large result sets
- Filtering: By interest, creator, search
- Like System: Users can like/unlike posts
- Interest Tags: Posts can be tagged with interests
- The service uses MySQL connector with dictionary cursor for JSON-like responses
- ETag is generated from post data for optimistic locking
- Like counts are calculated dynamically from PostLikes table
- All datetime fields use ISO 8601 format
When adding new endpoints:
- Add route to
routers/posts.py - Use
get_firebase_uid_from_header()helper for authentication - Add proper error handling and ETag support
- Update this README with endpoint documentation