I’m kind of a developer who likes to do futureproof code and sometimes question decisions that impact on future requirements. Fore example, if there’s a service where a user has a profile, why won’t we separate those into two models so in future if/when we want to have multiple profiles per user, we just need to change “has_one” relation to “has_many”. It also means proper test coverage and code split in meaningful classes. In short: no shortcuts.
However, there are times when shortcuts are fine and are required. One of those cases is when your doing POCs (proof of concepts). I encountered this recently and would like to share some of my findings.
Project X was an app that’s integrated to one external service A. Up to this date, that one service had been enough for the app as a source of the data. So some architectural decisions had been made of that. Now, with this POC, I had to jump into that project and integrate a second service B (which I had integrated in another project already, so I knew how to do it).
We held a meeting with a few key individuals from the project X team and in the end we came up with a good plan. Our goal was to get a list of items from the service and show them in the mobile app. So let’s start.
The external service is using oauth2 and has expiring tokens. Existing system did not support that kind of behaviour, so changes needed to be made. New API endpoint(s) for the mobile client -> changes needed. API tokens needs to be stored somewhere -> changes needed. New items will need to be updated at some point -> changes needed. So at least these three changes will need to be made:
- New endpoints
- Store the tokens somewhere
- Add support to refresh data from this source, as current architecture does not support it
Last two items are quite big ones (in the terms of coding) as those possibilities with the existing architecture have not been though in the first place. Next step is to think about some estimations and tasks that are required within the POC. The goal of our POC was: Show items in the mobile app.
Okay, we definetely need the endpoints for supporting oauth2 flow. At this point, it’s easy to create some hardcoded route, but if we use parameter to define the service to be used, we can take it in as a value and thus build the system to get settings related to that service in the background -> new services can be connected pretty much by just adding new settings. It will make future changes much smaller.
Then we need to store the tokens when requesting the callback handler. We pause and realize that to meet the POC’s requirements, we don’t need to actually store the tokens. Just fetch the tokens by the authorization code and get the items directly in the callback handler. Win!
Now that we have the data, we need to convert it to fit into the existing item’s structure. This means there will be no changes in existing architecture because of that. Can’t be counted as a win as it’s what one should do and would have been done anyway.
Then the data refresh. Why do we need that? Well, to meet the POC’s requirements we don’t. So lets forget that. Another big win!
In the end almost all of these changes were done by additions, just some minor changes was need in the existing architecture.
During the final moments of the POC we received this comment, “But I can’t take that code to the production!”
Yep, you can’t. But that wasn’t the intention at the beginning. Idea was to have a POC. It wasn’t meant to be shipped to production right after. For me POC’s are (and in generally they should be) the quickest and easiest way to test thing X. Take all the shortcuts you can and focus only on the requirements when planning. Also the scope and requirements for POC should be quite simple. If you want some data from external service, it’s probably enough to get just smallest subset of it, not all that you would use in the production code.
Shout out to Chris Moore for proofreading and helping with the post