URL Shortener example with OWIN
- Posted in:
- Web dev
Inspired with this blog post: http://grasswire-engineering.tumblr.com/post/94043813041/a-url-shortener-service-in-45-lines-of-scala, here goes c# / OWIN version! Its not meant to be used anywhere, but more as a learning example how to leverage some new tech stuff that’s available.
First example is using Katana, Microsoft implementation of OWIN standard, running as a regular ASP.NET application, meaning on System.Web, meaning with IIS (Express). I didn’t use any high-level class for dealing with requests, http context and response, expect what comes from Microsoft.Owin, in purpose just to show how it looks like without any framework on top of it.
For database, I picked RavenDb Embedded. At first I planned to use EntityFramework 6, because one of the requirement I put to myself was Async ability of db engine – just to plug that in to async OWIN stuff, but since everybody knows about EF, and not everybody about Raven, I just went with Raven in this example.
App works like this:
To generate short URL, you send a POST request with query string “path” that contains value of URL you want to shorten. For example: http://localhost:12345/?path=http://www.hudosvibe.net. As a result, you should get HTTP status 201 (created), and a hash for this URL.
To use it, just add that hash to the URL: http://localhost:12345/hash-goes-here
And that’s it, nothing much more going on!
Now, to the interesting part, here’s the code:
The complete source is on Github (https://github.com/hudo/Sample-UrlShortener), where I’ll put other example hopefully in the near future!
How does it work:
For OWIN, well Katana, because OWIN doesn’t specify that, we need an entry point to our application. By convention, that’s the Startup class, and Configuration(IAppBuilder app) method.
As you probably know already, OWIN is series of middlewares that executes in sequence. Middleware is just a function that gets the http context and a reference to the next function. I created only one middleware here, a method closure which will be called for each request.
Just to avoid using IF or SWITCH, because that’s not so cool anymore, I created a dictionary with actions for each Http method, GET and POST. With await actions[ctx.Request.Method](session); appropriate action is executed, based on requests method.
For get request, we’ll try to load a Raven document by Id, and send a redirect to a full Url address. For post, we need to create a hash first. In this simple and naive example, we’ll just create random sequence of 7 characters. There can be conflicts, and document will be overwritten – that’s how Raven works if you manually set Id. We store that document to Raven, with hash and original full Url.
Raven is running in embedded mode, which means you don’t have to have Raven server on your computer, it run in process, with managed store engine (slower, but just fine for this example). It uses Json serialization, so anything that can be serialized can be stored. No need to create a schema, we just store json object, and Raven takes care about the rest.
Think that covers it. Next on the list is example with Nancy and ASP.NET vNext, so stay tuned for updates!