URL Shortener #1: Design
How do we go about designing a URL shortener? This series of articles contrasts the Java and Xtend languages around a very simple URL shortening REST service. Xtend is a JVM language that compiles into readable Java and is fully compatible with all Java frameworks, libraries and tools. If you know Java you already know most of Xtend! A presentation is also available
Our URL shortener is an online REST application that converts a regular HTTP URL into a condensed format redirecting to the original long URL.
This article series consists of 4 documents:
- This post’s discussion of the service’s general design, expressed in a more or less language-independent fashion through UML diagrams
- A Java incarnation based on very simple frameworks and libraries that don’t get in the way of understanding the implementation
- The Xtend implementation of our service’s
Main
method explained step-by-step, in contrast with its Java sibling - The Service Xtend implementation for the URL shortener as such along with its various dependencies
In the name of brevity and simplicity, certain aspects of this example service have been omitted. This includes concerns such as hash collision, authentication and authorization or persistent storage recovery.
The Domain Model
Our URL shortener exposes functionality to:
- Shorten a long URL
- Redirect to a long URL given its short version
- Delete a short URL
Fulfilling these requirements has two aspects:
- The shortening of any arbitrary
String
by means of a (non-cryptographic) hashing function. We call this interface aShortener
- A means to persistently map a short URL to its long URL counterpart. This interface opens a key/value store exposing its functionality as a regular
Map
fromString
(the short URL) toString
(the long URL).
The
UrlShortener
methods shown above (shorten
,redirectFrom
anddelete
) reflect this class’s responsibilities but the actual implementation is different (and simpler).
Using interfaces for the shortening and storage concerns allows for an open-ended set of interchangeable implementations.
Thus, for shortening, we could use the murmur3
or sipHash
hashing functions.
For storage, we could use an in-memory map provider or some embeddable key/store persistent storage engine such as ChronicleMap
or Berkeley DB
.
Given these interfaces, UrlShortener
’s shorten(longUrl)
sequence diagram would look like:
The redirectFrom(shortUrl)
works like:
Finally, the delete(shortUrl)
sequence diagram is:
Domain Class Diagram
An overall class diagram is:
Note the inclusion of a Main
class responsible for locating a configuration resource file by name and then using it to create a ready-made instance of UrlShortener
.
Implementation Notes
Since we’ll be implementing our URL shortener in both Java and Xtend (which has the same semantics as Java) we selected Java libraries and frameworks that maximize easy of implementation while still enabling us to develop a fully working REST service.
The libraries and frameworks selected are:
Guava’s
Hashing
class which supports themurmur3
andsipHash
algorithms suitable for string shorteningChronicleMap, a fast, embeddable Java key/value store exposing its functionality as a
Map<String, String>
SparkJava, a dead-simple microframework to write REST services. Nothing to do with Apache’s Spark; the official name is
SparkJava
SnakeYAML, the de-facto standard for processing Yaml in Java
We can now proceed to examine the Java implementation