Exposing private "API" through RESTful public API RRS feed

  • General discussion

  • I work for a medium sized company that's been around for ~12 years.  Our software package is running in over 10,000 retail stores across North America. It's based on WPF and uses WCF over HTTP for the server side.  My team is being tasked with creating a public API and we're well on our way to restructuring the different layers using more OO patterns, dependency injection interface style development, hypermedia, etc.  The problem we are facing at the moment is a potential "Version Hell".

    Since our deployed client software is currently a Fat client, we typically have up to 10 versions in the wild.  The bulk of our clients move along with regular updates, but some smaller companies and many of our largest companies are slow to adopt the latest greatest features.  Versions may differ simply as bug release non breaking changes, or new features along with bug fixes, or sweeping changes to a particular area of the software.  Typical software versioning I would guess.  Each company we service has their own database, which means the "Customer" table for one client on v1.0 may be very different from the "Customer" table in v1.5.

    We have a heavy investment in SQL Server, using .NET 4, we have a home-baked code generation tool that generates much of our data access layer using DataSets/DataTables/DataRows to move data around our application layers.  Obviously, this doesn't fly in the RESTful world.  We need to expose some sort of POCOs, so we'll have to map from our current "Private API" to the objects we'll be exposing.  Compound this with the fact that the public API may be accessing any client on any version, and we have possibly multiple mappings.

    Thanks for staying with me this far...  This is a huge question with lots of variables and I'm not sure 3 paragraphs adequately describes the landscape.  My very general question to the MSDN blogosphere is this:  How the hell do we do this?  Ok, maybe I'll try to clarify a bit.

    1) Does anyone have experience they can share with a similar situation (multiple versions on the back end, multiple versions on the front "API" end, and the mapping between)
    2) What is a good strategy for taking existing private services (i.e. GetCustomerByID(ID), or CustomerSearch(searchTerm)) and turning these into a resource like http://my.api/v1/Customer/55243 or http://my.api/v2/Customer/Search/"bob smith"
    3)Any examples, whitepapers, blogs, etc that anyone is aware of or third party software, or cool architectural paradigms to shed some light on this BIG BLACK BOX we're calling "The Mapper"?

    I'm willing to answer any questions to help get us going in the right direction.  We've considered implementing a contract (Interface) that the API would own and forcing the private API to implement services to fulfill that contract, but this is very tightly coupled.  We're also tossing around the idea of using some sort of XML mapping definition file/data to drive the mapping process, but this lacks compile-time checks.  Nothing seems particularily friendly at this point.  I'm very open to suggestions.

    Thanks for your consideration.

    Wednesday, April 25, 2012 10:09 PM

All replies

  • I guess my first question would be, why do you want to go to a REST approach? In general, REST implies that you have a loose contract and it supports more dynamic clients. In your case, you only have one client for your services, and you have full control of that client (other than version control). I'm sure others may have different opinions, but it doesn't sound to me like you have much to gain from a REST approach.

    For the version issue, you have hit on the #1 issue of API design. You cannot change your public contract without serious implications. Typically I have dealt with this by exposing interfaces, rather than concrete types. For example, in your case you can expose an ICustomer interface, which includes the bare minimum of customer information which was included in v1. Each time the Customer contract changes, you would derive a new interface from ICustomer defining the new data which you're adding. Your service exposes the ICustomer interface. On the client side, you can derive the correct sub-interface for the version you're on, if needed.

    That said, if you want to go with the REST approach, the new ASP.Net Web API may be a good way to go. You can use either a custom routing table or different methods in your Web API controller to determine what objects you're returning. From there it's just a matter of writing a layer which takes your domain object and maps the properties onto the correct DTO you need to return for that version. AutoMapper could work well for that, with different registrations for different versions of the DTO,

    Check out My Blog. Now updated to actually work!

    Thursday, April 26, 2012 3:31 PM