This is a small microservice, resposible for handling bid amounts for our Pay Per Click bids platform. Other applications use this service to know what is the bid amount for a combination of country, category, and channel.
- Bid: The amount a vendor bids to pay for a click in a given country, category, and channel.
- Country: ISO 3166-1 alpha-2 country code. This microservice does not care about country names or any information other than the code.
- Category: A string code for a given category in our websites, for example: crm, finance, sports, hr...
- Channel: The string code for one of our websites. Capterra: ca, GetApp: ga, Software Advice: sa
Bids are organized into defaults and overrides. Bidders are allowed to enter in bids that target a specific country, category, and channel, or, they can provide defaults at either the country, or, country/category level.
Given a sample bids table containing the following data:
country | category | channel | amount |
---|---|---|---|
us | finance | ca | 4.0 |
uk | sports | * | 3.0 |
us | * | * | 2.0 |
* | * | * | 1.0 |
this means that:
- The bid amount for the
us,finance,ca
combination is$4.00
- The bid amount for
uk,sports
in any channel would be$3.00
- Any combination in the
us
other thanus,finance,ca
would have$2.00
bid amount - And any other combination would have
$1.00
as bid amount
The challenge is to create a /bids
API endpoint that would allow other applications to request the bid amounts for different country, category and channel combinations. The endpoint should accept comma-separated lists of countries, categories and channels as parameters, and return a JSON object containing the array with all the combinations and the amount for each.
Sample request:
GET /bids?countries=us,uk&categories=finance,sports&channels=ca,ga
And the expected response is:
{
"bids": [
{ 'country': 'us', 'category': 'finance', 'channel': 'ca', 'amount': 4.0 },
{ 'country': 'us', 'category': 'finance', 'channel': 'ga', 'amount': 2.0 },
{ 'country': 'us', 'category': 'sports', 'channel': 'ca', 'amount': 2.0 },
{ 'country': 'us', 'category': 'sports', 'channel': 'ga', 'amount': 2.0 },
{ 'country': 'uk', 'category': 'finance', 'channel': 'ca', 'amount': 1.0 },
{ 'country': 'uk', 'category': 'finance', 'channel': 'ga', 'amount': 1.0 },
{ 'country': 'uk', 'category': 'sports', 'channel': 'ca', 'amount': 3.0 },
{ 'country': 'uk', 'category': 'sports', 'channel': 'ga', 'amount': 3.0 }
]
}
For data storage, the code already provides a model mapped to a relational database table, but feel free to explore other solutions.
The app can be run either locally or using Docker. If Ruby 3.1 is not installed in the local system, Docker can be used for convenience. The repository contains a docker-compose.yml
file. Examples:
$ docker-compose run app bundle exec rspec
$ docker-compose run app bundle exec rails console
Please create a pull request in this repository with:
- A well written and performant solution, implemented in Ruby.
- The tests must pass
- Add as many tests as you think you need
- Good PR description containing your solution explanation as well as any pertinent information
- You can use whatever libraries you would like, as long as they can all be installed using bundle install. Please explain and justify your library choices in the PR description
- Correctness: solutions must produce correct result sets given any valid input
- Readability & Organization: code should be well organized and readable with well thought out architecture and naming choices
- Well-organized git history is a plus