alanhay / qikserve-sample

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Overview

This is a simple command line application that will populate a random basket of goods and print an invoice to the console.

The products and discounts are available via a REST API provided by Qikserve and which can be consumed by running the provided Wiremock service.

The generated output will look like the below:

sample output

Building and Running

Clone the repo: git clone https://github.com/alanhay/qikserve-sample.git
cd qikserve-sample
unzip qikserve-wiremock.zip
cd wiremock
start.sh // server should be running at http://localhost:8081
cd ..
mvn spring-boot:run

Design Principles

  • design a domain model to be independent of the data source. When data comes from a REST API then use Jackson configuration, processing and mixin classes to map the incoming data to this domain model. The application could be switched to fetching product data from a database simply by adding a new implementation of uk.co.certait.qikserve.service.ProductService.

  • make it possible to add new types of discount (see further below) without changing existing code (open closed principle).

  • make it possible to handle different currencies. Not all currencies have 2 decimal places for example. See the commented code in the main class for examples of running for different currencies.

** The domain model is not quite as I would like due to limitations of the provided REST API.

Limitations

The REST API allows for multiple promotions per Product. The domain model reflects this however I have not had time to handle > 1 promotion per product. Therefore the JSON processing code will only populates the model with the first promotion should there be > 1 specified for a product. .

I have not added any validation of the data, exception handling, logging etc. Let's assume I can do that.

Adding New Types of Discount

In line with the Open Closed Principle, it should be possible to add new types of promotion without modifying existing code. We can do so by creating a new implementation such as the below. With this class in place it is simply then a case of updating the application configuration to handle the new type of discount: no business logic needs to be updated to handle this new type.

The Configuration to be updated is the registration of the new sub-type in uk.co.certait.qikserve.json.ProductDiscountMixin. Optionally (not required for the below) is the creation of new Mixin class and registration of this in uk.co.certait.qikserve.configuration.ApplicationConfiguration

public class FlatMonetaryValueProductDiscount extends BaseProductDiscount {

	private int amount;

	@Override
	public int getMonetaryValue() {
		return amount;
	}
	
	public int getAmount() {
		return amount;
	}

	@Override
	public String getDescription(Locale locale) {
		return formatMonetaryValue(locale, getMonetaryValue()) + " off " 
		          + getQualifyingProduct().getName();
	}
}

Follow Up Questions

1. How long did you spend on the test?

A couple of days.

2. What would you add if you had more time?

As noted above, more than 1 promotion per product is not handled. I'm not sure if this would be a valid case (even though the JSON representation allows it). Could look at handling this.

3. How would you improve the product APIs that you had to consume?

  • possibly add an end-point for discounts.
  • possibly add a back-reference from discount to product.
  • possibly break the relationship from product > discounts
  • add HATEOAS links for navigating the API.

4. What did you find most difficult?

  • dealing with the limited API and mapping this to the domain model.

5. How did you find the overall experience, any feedback for us?

Took a bit too long to be honest. Maybe for a permanent job but for a contract role.... There are hundreds of ways of solving this. Any assessment is always subjective.

About


Languages

Language:Java 100.0%