Making your big app a little Glitchy around the edges

Jude Allred
Glitch: Make Better Software
9 min readOct 3, 2017

A story about using Glitch-powered microservices to add real functionality to large, preexisting web applications. I’ll show you how we added support for Slack Classic URL Unfurling, a feature useful in just about every web app. If you like my approach, there are resources at the end to help you explore this path in your own software.

The problem we set out to solve

Slack has grown wildly popular and users of our (and your) software are expecting it to place nicely with Slack. When folks share links in Slack, they’ve come to expect rich content to “unfurl” into the chat channel, enriching the link. Links to FogBugz didn’t have this behavior.

User expectations are on Slack’s side now. When they see a link in chat, they expect a richer, cleaner format to unfurl.

The solution space

If you’ve written a dedicated Slack application to connect with your web app, and your users have chosen to install it, you can use it to collect and unfurl links. Unfortunately, for any Slack account that doesn’t have the app installed, you don’t get the fancy unfurl behavior.

Enter Slack Classic Unfurling, which allows anyone who is in control of their HTML responses to send context to Slack which emits pleasantly unfurled links, and with no configuration necessary on the Slack end! Implementing just this small piece puts us in control of the content that Slack renders during the unfurl. (See Matt Haughey’s tremendously helpful article on unfurling for more details on these mechanics.)

Furthermore, if the unfurl response comes from a real live web server instead of simply some hard-coded meta tags in an HTML page, we can make use of whatever additional context we can find in order to generate richer dynamic content on the fly. The context we have to make that content meaningful is limited — the link itself plus whatever other public content you can pull from — but there’s still a lot we can do with dynamic powers.

An example of a dynamically generated “classic” unfurl provided by the Slack Classic Unfurling Glitch app. Linking to it in Slack, e.g. https://slack-classic-unfurling.glitch.me/The-Judgening , will mad-lib some text and images into an unfurl, providing a simple yet powerful proof of concept for dynamic classic unfurling.

The problems in how we set out to solve it

We can predict a few things about this feature:

  • We’ll get feedback about it, both internally an externally, and we’d like to be able to respond rapidly with phrasing changes and bug fixes.
  • 3rd party integrations are moving targets, and Slack is an especially speedy one at that. If they change how unfurls appear, we want to be able to keep pace with them.
  • It’s a new feature, so it starts out as a proof of concept, and we’d like to prove it out today, not next deploy.
  • It’d be easy to scope creep on this feature, and there are a number of ways to keep that in check. If we’re able to iterate quickly, then we’ll be able to ship a smaller feature and build from there based on success and reception there rather than having to spend more time in a speccing and research phase.
  • Unfurling logic will touch on the part of our code base which does global request routing. That’s an area of the code that we make changes to slowly and deliberately, since bugs introduced there can be very expensive. This cadence would be at odds with the bullet points above.

Assessing this solution space with an eye towards a large preexisting code base, I sense that if we implemented this feature at all, we’d probably make a little nicely-isolated little library within our monolith and responsibly dispatch some requests over to it when unfurls are needed. It’d be pretty easy to go about, but the speed of iteration in that code would be lock-step with the speed of iteration on the app as a whole, and that’s at odds with some of our predictions about this feature: It’s absolutely the sort of thing we want to prototype and iterate on rapidly.

A tangent on Big Software Applications (and the butterflies of inspiration)

Most software, as it ages, grows. As it gains functionality and resiliency, it’s almost unheard of for its code-build-test-deploy cycle to happen in seconds. Great teams in supportive environments can keep this down to hours or even minutes, but even in the shining examples of good programming practice there are shadowy corridors where programmers’ fingers tread lightly and rapid iteration takes a hit.

A funny thing is that for all of our tech bravado, it’s not us software developers who tend to have the shortest time from code-written to customer-facing deployment. No, it’s our marketers. The folks authoring our blogs and iterating on our websites tend to have the lowest barriers between inspiration and deployment.

This gives them superpowers. They can react to the world, and to customers, in real-time. They can more easily clutch the butterflies of inspiration that land on their shoulders. They can more rapidly respond to the latest meme.

I believe this is because we have a clearer view of the value of letting marketers rapidly iterate and publish. They don’t want to wait minutes (let alone hours, days, or weeks) to push their changes through an app deployment pipeline, and devs don’t generally want to handle a stream of urgent deployment requests from a dev-marketer.

And so there exist good tools for marketers because devs are good at writing tools that solve problems that they can see, and feel, and be frustrated at. Websites can be hosted from blog platforms, content management systems like Wordpress, and wondrous new technologies like Glitch. #ILikeGlitchForManyPurposes #Spoilers

Good for them! They deserve good tools that promote rapid iteration and emphasize shipping! They can have those while we devs trudge through our Gitty fields and stop off at the friendly-named-CI program of the year that’s letting us know that our test framework of yesteryear isn’t passing and … huh.

Now then, developers, why can’t we live-code and live-deploy responsibly? Why must your features, once adequately tested and vetted for their scope, be held from release while the gears of the infrastructure you built grind away, your loyal and ever-lagging servants? Take back the Read-Eval-Deploy-Loop!

Heh, okay, well, there are a lot of reasons why not. Lots of really good reasons, mostly related to up time, security, and generally being responsible engineers taking care of an important application.

Processes tend to be well-reasoned. The trouble is that the development processes we put in place for app security and reliability, among many others, are quite different from the processes we might desire for fixing a typo or playing with the phrasing of an interaction with a chat bot.

We know a common way to go about fixing this. Break your app apart; separate the frontend from the backend and break the backend into a collection of microservices. And to each component, their own team! Their own workflow best suited to its own needs! Their own.. hmm.. set of development tools and practices? Their own getting-started guide? Their own servers and monitoring and… Ok maybe let’s stick to the monolithic side of things, but we’ll keep it majestic and make sure the parts that move the most remain well-oiled.

There are a lot of tough calls to make in the architecture of a large web application, especially in keeping your rapid iteration abilities in harmony with stability and security.

I made a new sort of call in order to address the Slack Unfurling feature, and I wanted to share it with you. I added a new microservice to our large SaaS application, FogBugz, and it’s powered by Glitch.

We now have a Glitch microservice powering real functionality in a real, 16 year old, production web application. I can change that functionality with a keystroke to a code base that’s both open-source and trivially shareable. It safely integrates a large web large application biased toward resilience with a small (but meaningful) application intensely biased toward rapid iteration.

The solution

A glitch powered microservice! We add a small amount of glue on the FogBugz side, make sure the interface is simple and resilient, and then build out all the functionality of the Classic Unfurling on the Glitch side of things.

The “glue” consisted of some changes to make in FogBugz, but their scope became very small: Sniff requests for the Slack Unfurl user agent, redirect those requests on to our Glitch unfurl app, and append the original URL as a request parameter.

Unlike a typical web request which FogBugz would response to directly, unfurl requests are redirected over to our Glitch microservice. The Glitch unfurler gets its context out of URL parameters that we added in the redirect step (such as the originally-requested URL) and composes its unfurl response for Slack.

Making the solution visible was a matter of getting this routing change deployed to our dogfooding environment, then living in the Glitch app for a few days to capture the natural interactions we were having in chat and respond with ever-improving unfurl content.

As we dogfooded the new unfurls in our company Slack, we were able to iterate and play very rapidly. We learned about things that folks were using which didn’t unfurl properly, helped spread awareness of the feature early in its development cycle, and accomplished a lot of phrasing polish:

It wasn’t obvious how to display unfurled search queries, so Gareth, Adam, and I iterated in chat. I could make a phasing adjustment in the Glitch app and then paste a new url into chat to see the new unfurl result play out. No mockups or roleplaying here, just real functionality changing in seconds as we dogfood.

“Shipping it” (to customers) came down to a judgement call on whether we felt it was polished enough to share. Since we wrote the slow-moving code up front (the “glue”), we already had that ready in production and gated behind a feature toggle by the time the phrasing and functionality of the unfurls had settled. And of course, the Glitch app server was live the whole time.

And of course, it’s alive and deployed right now — link to FogBugz from your slack instance to see the results, and if you’re so inclined you can peek at the source code to figure out how it was generated.

Builder’s notes

When I tackle a technical exploration in glitch, I like to start by building a general-purpose proof of concept. I eschew the business logic that I know I’ll need for the real thing (the work that takes most of the development time but has little risk of failure) and instead focus on the tricky bits.

I started by building the Slack Classic Unfurling Glitch app as an exercise in learning about unfurls and to determine if they’d be suitable for FogBugz. I quickly learned that they’d be both desirable and well-suited to a Glitch prototype, but it remained an open question as to if I could rely on my Glitch implementation or if I’d have to host the final product in FogBugz itself.

While building the prototype, I was able to notice that unfurl requests from Slack come with a special user agent. This opened up my next hypothesis — would the slack unfurl agent follow redirects? Only one way to find out.

I whipped up an unfurl redirect tester and signs pointed to “yes”. As a bonus that came up down the line, it turned out that the implementation in the tester here mirrored the implementation we needed to add to FogBugz to bring the redirects to life.

Et Voilà! Recap and resources

FogBugz now supports Classic Link Unfurling in Slack, and it’s powered by Glitch. It’s not the biggest feature in the world, but I’m proud to have our large mainstay SaaS application expand its feature set, rapidly and elegantly, by leveraging the tooling and philosophies of Glitch.

I invite you to view the source over in Glitch, specifically:

  • The FogBugz Link Unfurler, which receives unauthenticated requests from FogBugz and serves up appropriate HTML metas to enact the unfurl.
  • The Redirect Tester, to give you an idea of the sort of logic we had to add on the FogBugz side of things to wire this together.
  • And a totally generic Slack Classic Unfurling glitch app, which provides a concise starting point for building out your own unfurling logic, no matter if you end up using Glitch or building it into your own application.

If you end up playing with these, feel free to ping me @blinkymach12 with questions, comments, or advice. If I’m free, I’ll jump in and pair program with you.

I hope that next time you’re looking at building a new small feature into your old large project, you’ll consider being a little Glitchy around the edges.

--

--

Jude Allred
Glitch: Make Better Software

Software developer. Servant leader. Fog Creek’s Alumni CTO. Co-founder @ HASH.ai. @blinkymach12 https://allred.nyc