I am working on a REST API for a company that, until recently, has been focused on the Australian market. The result of this is that the API has resources and fields which model the Australian market, especially in relation to taxation, superannuation etc. We are now looking to move into overseas markets, starting with New Zealand.
Obviously there will be some degree of overlap between the two, but how do people go about handling the differences in terminologies and concepts, and how best to switch between them? For instance, the API might return a list of employees employed by a company; some of those employees are based in Australia, and some in New Zealand. An employee's tax details will have a unique identifier provided by the relevant taxation office (ATO in Australia, IRD in New Zealand), a basic salary, a contracted weekly number of hours, and a default taxation code (a Tax Code in Australia, and a Tax Scale in New Zealand).
How would you go about surfacing that information in a REST API? I want to avoid an EAV approach as much as possible; does that mean I need to go for some sort of inheritance-based model?
e.g.
public abstract class TaxDetails {
public string EmployeeReference { get;set; }
public decimal BasicSalary { get;set; }
public decimal HoursPerWeek { get;set; }
}
public class AustraliaTaxDetails : TaxDetails {
public string TaxCode { get;set; }
}
public class NewZealandTaxDetails : TaxDetails {
public string TaxScale { get;set; }
}
or do I keep a "simpler" model and just not set values that don't apply in one region, and let the serialiser tidy up the model? e.g.
public class TaxDetails {
public string EmployeeReference { get;set; }
public decimal BasicSalary { get;set; }
public decimal HoursPerWeek { get;set; }
public string? TaxScale { get;set; }
public string? TaxCode { get;set; }
}
A third option would be similar to the second, but try to find a neutral term for fields which are semantically the same but just different in naming (such as TaxScale
vs TaxCode
). It feels like the worst of the solutions (especially because naming things is hard), and you still have to deal with cases where there are no direct equivalents between two different regions; and it will scale even worse when you start to consider more than two regions...
So. How do you good folks handle this sort of scenario?
According to your narrative, you have indeed a common model with several country-specific specializations. This situation corresponds in principle to inheritance.
But a REST API is something that you have to design without inheritance in mind, because for the client apps the question is how to consume a published API. It shouldnt worry about the internal model of the back-end.
The solutions are very similar to what exist in a traditional ORM mapping, except that its for API mapping:
So if its only about tax code and tax scale, the aggregated API looks ok.
External links referenced by this document: