The two requested services are Go modules in the user_service
and article_service
directories.
The services each have a separate database with only identifiers being shared.
Provides a gRPC interface to user tag preferences persisted in PostgreSQL.
Provides access to articles persisted in PostgreSQL optionally filtering by tags.
Inspired by a style suggested by Ben Johnson I read years ago (a more upto date look at it by him is available here: https://www.gobeyond.dev/wtf-dial/).
Our business logic lives here, working with data from Repositories via interfaces.
Our persistence layer.
Making use of Services, should only be concerned with the presentation layer they're implementing.
My library choice has been for ease of getting going or because wanting to try a library out (like uptrace/bun, although I regret this).
- DATA-DOG/go-txdb - easily isolate tests by running each in a transaction
- beme/abide - http snapshot testing, allows quickly writing cases and confirming/updating desired output
- caarlos0/env - easily marshal env vars into struct
- labstack/echo - http framework
- uptrace/bun - SQL ORM, while the fixtures saved me a lot of time I found the documentation to be lacking and ran into difficult to resolve issues with it
- google/go-cmp - diff lib allowing for easy assertions in tests with readable output
- go.opentelemetry.io/otel - OpenTelemetry implementation
- Proper authentication, keys
user1
anduser2
are hardcoded for now - Secure + encrypt services with TLS (plus mutual TLS authentication for gRPC)
Download dependencies for both services:
make vendor
Everything required to run is provided by the docker-compose file, bring it up:
docker-compose up -d
Once running initialise the databases and insert some test data:
DB_HOST=localhost make db_reset
You should now be able to test the two requested endpoints with:
http://localhost:8080/v1/articles/feed?auth_key=user1
and
http://localhost:8080/v1/articles?auth_key=user1&all_tags=1,2
All tests can be run as usual for go tests, or make test
is provided to run for
both of the modules.
Tests requiring the database are behind the integration
build tag and require the
docker-compose environment to be running.
Tracing is enabled and exporting to Jaeger, you can view traces here: http://localhost:16686/search
A startup company has a vision for a service that provides a tailored news feed to its users.
News will be acquired from a multitude of online sources. Each news article will be analyzed (using AI) and tagged with one or more keywords, before being stored in a database within the company's infrastructure. Users of the service are able to specify tags for news areas that interest them. When a user opens their dashboard, they should see a feed of the most recent and relevant news articles.
There are few architectural guidelines so it’s completely up to you; however, to support their growth, the company have opted for the microservice route. Obviously, a number of services are going to be required, but don't panic, we're not expecting you to implement everything (although that would be impressive)!
Your task is to implement two services as follows:
- A
user
service that will provide a user's chosen tags - A
news article
service that will provide a feed of news articles
The User
service is a microservice that stores each user's tag selection.
Protocol, method, signature, etc. - (TBD, by candidate!)
Role:
This endpoint is called by the News Article
service.
Behaviour:
For a given user, return all the tags specified.
The News Article
service is a microservice that stores news articles.
Each article must contain a Title
, Timestamp
and list of Tags
.
This service also provides an external endpoint that allows users to retrieve articles, filtered and sorted by their timestamp.
Protocol, method, signature, etc. - (TBD, by candidate!)
Role:
This endpoint is called from user's browser/phone/tablet.
Predicate
An article is included in the response if it has at least 1 tag matching those of the user.
Behaviour:
Return news articles, filtered by the tags of the current user.
Protocol, method, signature, etc. - (TBD, by candidate!)
Request must include 2 tags
Role:
This endpoint is called from user's browser/phone/tablet.
Predicate
An article is included in the response if its tags contain both of the tags specified in the request.
The product team mentioned that they might need to change these predicate values. Modifying both the number of tags in the request and that used in the matching criteria. So, bonus points if you make these configurable! ;)
Behaviour:
Return news articles, filtered by the tags included in the request.
- Handle all failure cases
- Your code should be tested
- Provide a
docker-compose.yaml
file for any third party services that you use - Provide a clear explanation of your approach and design choices (while submitting your pull request)
- Provide a proper
README.md
:- Explain how to setup and run your code
- Include all information you consider useful for a seamless coworker on-boarding
- Create a new branch
- Commit and push to this branch
- Submit a pull request once you have finished
We will then write a review for your pull request!
- Add metrics / request tracing / authentication 📈
- Add whatever you think is necessary to make the app awesome ✨