I did some googling, and I was directed to Software Engineering to ask architecture questions. If you know of a different forum that could help me, please direct me to it
I recently started learning about microservices, and would like to build an experimental app (the backend) just for practice. I’ll explain the app requirements, and after that outline my microservices-based solutions (and some doubts/questions I have). I’d love to get your feedback, or your approach to building this app using microservices.
Please note: I am a beginner when it comes to microservices, and still learning. My solution might not be good, so I’d like to learn from you.
The App (Silly App):
The purpose of this app is to make sure users eat carrots four times a week. App admins create a carrot eating competition that starts on day x and ends 8 weeks after day x. Users can choose whether or not to participate in the competition. When a user joins the competition, they need to post a picture of themselves eating a carrot. The admin approves/rejects the picture. If approved, the carrot eating session counts towards the weekly goal, otherwise it does not. At the end of each week, participating users are billed $10 for each carrot eating session they missed (for example, if they only eat carrots two times that week, they’re billed $20). That $20 goes into a “money bucket”. At the end of two months, users who successfully ate carrots four times a week every single week divide the money in the bucket among themselves. For example, assume we have users A, B, C. User A missed all carrot eating sessions for two months (puts $40 a week in the money bucket, so $320 by the end of two months). Users B and C eat their carrots four times a week consistently for two months. So users B and C take home $320/2 = $160.
Simplification: I wanted to start simple. Forget about money. Forget about admin approval. We can add that later. For now, let’s focus on a very simplified version of the app.
- User can signup/login/logout to app
- When a user signs up, they are automatically enrolled into the next carrot eating competition
- Users can post an image of him/herself eating a carrot
- Users can see a feed of other users images (similar to instagram, except all pics are of people eating carrots)
- Users can access their profile - a page that displays how they’re doing in the competition: I.e,for each week, how many carrots they ate. And which weeks they failed at.
- At any point in time, users can access a page that shows who the current winners are (i.e, users who did not miss a carrot eating session yet).
Is this an appropriate simplification to start with?
Thinking Microservices - Asynchronous Approach:
Auth Service: Responsible for Authenticating User
Database:
- User Table: id, username, email, password
Routes:
- POST /users/new : signup
- POST /users/login: login
- POST /users/signout: signout
Events:
- Publishes
- User: created
Image Service: Responsible for Saving Images (upload to Amazon S3)
Database:
- User Table: userId, username
- Image Table: imageId, userId, dateUploaded, imageUrl
Routes:
- POST /users/:userId/images: Post new image
- GET /users/:userId/image/:imageId: Return a specific image
- GET /images: Return all images (Feed)
Events:
- Publishes:
- Image:created (userId, imageId, imageUrl, dateUploaded)
Competition Service: Responsible for managing competition
Database:
- Competition table: id, startDate, duration
- User table: id, username, competitionId, results (see below)
Routes:
- POST /competition: create a competition
- GET /competition/:competitionId/users/:userId: get results for a specific user
- GET /competition/:competitionId/users: get a list of users participating in competition (see below)
- GET /competition/:competitionId: get a list of winners, and for each looser how many workouts they missed
Events:
- Listens:
- User:created
- Image:created
In the database, user table, Results is the JSON equivalent of
results = {
week1: {
date: 'oct 20 2020 - oct 27 2020',
results: ['mon oct 20 2020', 'tue oct 21 2020', 'thur oct 23 2020'],
},
week2: {
date: 'oct 28 2020 - nov4 2020',
results: ['somedate', 'somedate', 'somedate', 'somedate'],
},
week3: {
date: 'nov 5 2020 - nov 12 2020',
results: [],
},
...
}
Better ideas on how to store this data appreciated
GET /competition/:competitionId returns
const results: {
winners: [{ userId: 'jkjl'; username: 'jkljkl' }, { userId: 'jkjl'; username: 'jkljkl' }];
loosers: [
{ userId: 'kffjl'; username: 'klj'; carrotDaysMissed: 3 },
{ userId: 'kl'; username: 'kdddfj'; carrotDaysMissed: 2 }
];
};
What do you think of this? How would you improve it? Or would you approach this from an entirely different way?