Initial interview project for Zhipeng Jiang @ Confluent.
We want to make a feed reader system. We will have 3 entities in the system: Users, Feeds, Articles. It should support the following operations:
- Subscribe/Unsubscribe a User to a Feed
- Add Articles to a Feed
- Get all Feeds a Subscriber is following
- Get Articles from the set of Feeds a Subscriber is following
Requirements
- Write a service with HTTP endpoints that allow items 1-4 from above
- It should handle multiple concurrent clients
- It should persist data across restarts
- Supply a README explaining your choices and how to run/test your service
The solution comes up with a basic web service that provides HTTP endpoints to manipulate the data model, with a basic MySQL database as data persisting layer.
Create a local database or use a public MySQL service hosted on AWS or Azure, or launch a local MySQL container, etc. Put the database access credential in src/main/resources/application.properties
.
Once database is created, initialize the database with a SQL script located in data/db.sql
. You can do this from a MySQL client, like MySQL Workbench, Sequel Pro, etc. Or you can imported it from MySQL command line too by typing in the full path of sql file.
Project can be imported to IntelliJ IDEA, or simply use maven to resolve dependencies and run tests and build.
If you use IDEA, you can import the project first, IDEA should be able to resolve all the dependencies automatically according to pom.xml
. Right click on src/main/java/me.zpjiang/FeedsApplication
and choose Run FeedsApplication
, it should help you to launch the service from IDEA.
If you use maven, you can run mvn compile
to compile the project, dependencies will be downloaded automatically if they do not exist. Run mvn spring-boot:run
to launch the project.
mvn compile # compile the project
mvn spring-boot:run # run the project
In order to support operation 1 to 4, I have to develop a basic data model to persist three entities: User
, Feed
and Article
.
Considering that a user can subscribe multiple feeds and a feed can be subscribed by multiple users, thus it is a many to many
mapping between User
and Feed
. Similarly, a feed can have multiples articles while an article can be published into multiple feeds, thus it is also a many to many
mapping between Feed
and Article
.
I created two new tables to store the mappings Subscription
and Publication
.
For the four operations mentioned in the requirements, I've implemented the following APIs:
POST /sub/user/{userID}/feed/{feedID}
Success: 200 OK
Failed: 400 Bad Request with error message
DELETE /sub/user/{userID}/feed/{feedID}
Success: 200 OK
Failed: 400 Bad Request with error message
GET /feeds/{userID}
Success: 200 OK with an array of feeds in JSON format
Failed: 400 Bad Request with error message
POST /feeds/feed/{feedID}/article/{articleID}
Success: 200 OK
Failed: 400 Bad Request with error message
GET /articles/{userID}
Success: 200 OK with an array of articles in JSON format
Failed: 400 Bad Request with error message
Import Confulent.postman_collection
, it contains the list of five operations and test data.
One possible step is subscribe feed
list feeds
, publish article
, list articles
. The service should be able to handle an abnormal step, e.g. unsubscribe before subscribe.
Don't forget to start the web service first before running Postman.
In IDEA, you can choose to run /src/test/java/me/zpjiang/FeedsApplicationTests
, which covers most of use cases for Feeds.
In IDEA, you can also shoose to run /src/test/java/me/zpjiang/FeedsApplicationConcurrentTests
, which creates 10 threads to perform sub/unsub and publish actions simultaneously.
run mvn test
directly, it should be able to run both E2E tests and concurrent test cases.