in MealMind

Making MealMind #5: Sync Thoughts

I’ve been thinking a lot about how to synchronize data between the MealMind server and clients. The proof of concept app I have is a web app and there isn’t any persistent state once you navigate away from the app. For the “real” version, I feel like it has to be a mobile app. For shopping, I’d rather have the shopping list on my iPhone and for planning, it’d be easier to actually drag and drop on an iPad. Some people may prefer a web interface, so it’ll likely exist as well, but I think this is definitely a good case for a “mobile first” approach to getting the thing launched.

I wouldn’t mind making it a progressive web app (PWA) since that would certainly solve the issue of needing to build for iOS AND Android, but I’m not really convinced that PWAs are ready for prime time when you’re talking about an app like this. I can definitely see the app being used on multiple devices for the same account. I don’t know if people will use the app simultaneously though. Would a couple each open the app on their devices, sign in, and start meal planning together? Or would one person make the plan and the other may view it, but only one is really making changes. Same for the shopping list – if a couple goes shopping, will they split up and each mark things off the list or will one manage the list and the other focus on getting the item in the cart? Those sound like small differences, but it changes how the API has to work.

In the scenario where only one person is really making the changes at any given time, a “normal” REST-style API would work just fine. You don’t have to worry about multiple conflicting changes coming in at the same time since only one device is making the changes. That’s not to say it’s impossible to cause trouble – it’s still possible, but you can handle it by letting the server decide which change to keep (last one in, etc).

If, on the other hand, multiple devices can make changes at the same time to the same items, then you really have to think about keeping deltas for every change. For example, if a couple is entering recipes and one person is adding the ingredients and another person sees a typo in the recipe description, you would (responsibly so) expect the final recipe to have the correct description AND the correct list of ingredients. If you don’t track deltas for each piece of data that can change, you might end up either throwing away some of the ingredients or throwing away the typo correction.

The bad thing about all of this is syncing is really hard. I personally haven’t had to build out a true synchronization system, so I’ve been reading up on it. I’ve always been aware it’s one of those things that sounds easy but is incredibly hard. I’ve also heard (and can see how) it’s not something you can really do generically – so there isn’t an off the shelf sync solution you can just plugin in. That said, I’ve found Brent Simmons Vesper Sync Diaries to be incredibly enlightening. Brent has a handful of posts describing his thoughts as he worked out the sync process for the Vesper iOS app. It’s not the same data I would need to sync with MealMind, but many of the considerations & gotchas still apply.

At this point, I’m torn on how to proceed. On one hand, I kinda want to build out a shopping list app that uses a real sync so multiple devices can work with the data at once. I feel like the shopping list is the main place this scenario would happen so it would make sense to try to solve the hard problem first.

On the other hand, I’m tempted to start building out the app as a web app, almost like the proof of concept app, just so I can get it running and in the hands of other people. If I do that, it’ll be harder to later come back an integrate syncing though because you need pretty specific data structures to keep up with this stuff.

I think I’m going to stick with the web app initially and not deal with the real sync support initially. If I go down the mobile app + sync route right now, it’ll be months before I have anything to show. If I go the web app route, I can have something running in just a couple of months at most.