My First Experience with Server-Side Swift (using Perfect from perfect.org) – Part 2

November 19, 2017 0 By Pavan Tumati

 

In Part 1, I talked about why I chose Swift on the backend and my general overall experience using Perfect on the backend.  In Part 2, I want to talk about my experience using Perfect-Mustache and Perfect-Redis.  The gist of this post:  I hit some minor issues using Perfect-Mustache, but I was able to work around issues with small syntactic changes.  With Perfect-Redis, however, I hit some suspicious data corruption and, instead, had to switch to using Kitura’s (from IBM) Redis driver.   (I replicated the bugs and submitted bug reports.  If I manage to get some time, I will look into the implementation myself.)

For the record, despite encountering bugs, I am successfully using Perfect for one particular backend service in production and have not encountered any issues.  Life on the bleeding edge of technical endeavors sometimes involves, well, … bleeding.  Sometimes the bleeding happens on the user end, sometimes the bleeding happens on the vendor side.  C’est la vie.

Perfect Mustache

Perfect-Mustache is supposed to perform most of the functions provided by Mustache.js.  (Mustache.js is sort of a nice logic-less templating system.)  For my application, I didn’t intend to do much server-side rendering of content; I tried to keep any content rendering strictly on the client side (using React.js.)  Still, I wanted to dabble in some server side rendering to see what I could get away with.  The current implementation of Perfect Mustache doesn’t faithfully replicate all the features of Mustache.  For example, I tried to use the {{.}} syntax to render elements from an array of strings and this was not supported.  By creating objects instead of strings and providing a key to reference a given string, things worked fine.

My opinion:  If you end up using Perfect Mustache, the best way to go about using it is to look at the samples provided by Perfect and try to accomplish what you are trying to do by re-using examples provided by Perfect’s developer.  Usually the developers had good reasons for restricting functionality, or they encountered some hiccup dealing with data in one platform (Mac OS) vs another (Linux.)  In most cases, with Perfect, you can accomplish most of what you want by not venturing too far away from example projects.

Perfect Redis

Perfect Redis did some small things correctly for me, but did not work properly for my use case.  When I attempted to submit JSON-encoded objects to Redis, I immediately encountered problems.  The strings were not being encoded properly for JSON.  I had to write a Swift extension to encode the values properly on the way in.  (See GitHub pull request:  https://github.com/PerfectlySoft/Perfect-Redis/pull/7 — the developers accepted this.)  Things seemed to work, at first.  When I increased the size of the content submitted to Redis, I started getting crashes and corrupted data.  I submitted a bug request, but stopped pursuing the issue when I realized I had to dig further into talking to Redis than I had time for.  I filed a bug report and moved on.

I should add that there were some other gotchas I encountered while working with Perfect’s Redis drivers.  For example, calling something like a listPrepend() (i.e. LPUSH) function means that the callback can execute at any time in the future.  Subsequent code can execute before the results of a callback are known.  The documentation doesn’t hint that this node.js-style (asynchronous) of programming is the preferred approach of programming (although I suppose this becomes obvious to the programmer when things stop working properly.)  This situation could be a bit of a surprise to the unsuspecting.

Fortunately, I was able to drop in IBM’s Kitura Redis driver and was immediately able to get a functional solution.  Being able to swap drivers like this, I think, speaks highly of the current Swift ecosystem (at least with regard to constructing tiny web services.)  If all of Perfect doesn’t work for you, mixing and matching components from other areas in the Swift ecosystem works as a short-term fix.

You’re not always left stranded on an island of broken code in the Swift ecosystem.  🙂

Do I still plan to keep using Perfect and Swift on the backend?

In some cases.  In my case, where it was advantageous to take advantage of existing Swift code, I think Perfect managed to do the job nicely.  The framework’s code is easy to follow and it took very little time to get a minimalist API up and running.  (In fact, I have a production service in Swift running now with almost no downtime and have been incredibly happy with the results.)  In terms of runtime performance, Perfect has been more than satisfactory.

In terms of a general “which framework is best” sort of question, I think the verdict is still out.  I expect the Swift (and Perfect) ecosystem to advance leaps and bounds over time. However, a lot has to be said for the sheer amount of documentation and examples prevalent in other frameworks that have already become more mainstream.  As an example, as much as I prefer Swift to Javascript, the node.js ecosystem has evolved into a rather pleasant place to be with the sheer number of high quality projects out there.  The Swift ecosystem doesn’t currently offer quite as much, at least outside of Apple-centric product development.  There’s always trade-offs, and server-side Swift doesn’t feel hands-down-no-doubts definitively compelling — although much promise exists for the future.

On a final note, I’d definitely like to see Swift play a stronger role on the backend.  I would encourage developers to try their hands at tinkering with this ecosystem and contributing when possible.