Write a URL Shortener in 26 Lines of Code with .NET Minimal APIs

Dino Lozina
Infobip Developers
Published in
5 min readJan 13, 2022
Photo by Markus Winkler on Unsplash

I was looking forward to .NET minimal API framework for a very long time and now, it is finally out! Let’s dive into new version of .NET6 and answer the following questions:

  1. What is .NET minimal API?
  2. How to refactor existing URL shortener?
  3. How to add dependency to service?
  4. How to add endpoint to service?
  5. Where are using statements?

🤔 1. Introducing .NET Minimal API

”Do you need all of this stuff just to shorten URL?”

This was a first reaction of a friend (who happens to be a Python programmer) when I showed him my first shortner example.

“Yes” would have been a pretty accurate answer, but not the one that I’d be happy with.

There was a lot of boilerplate code compared to other frameworks.

One benefit is that the structure is already set up — very convenient when we have larger projects to tackle. On the other hand, not ideal when I need to create a small service as part of a microservices architecture.

Most SaaS providers are using microservice architecture for its scalability, smaller/faster deployments, and ease of understanding.

Take a look at the Flask API template:

In just 5 lines of code, we have our first endpoint! Single file, no other setup needed. All we need to focus on is the feature of this new service.

Now, let’s take a look at the initial .NET template. Out of the box, we get

Startup.cs, Program.cs, Controllers…a lot of boilerplate code. This could be unnecessary if the goal is to write one small service as part of a SaaS product or just a prototype.

Fortunately, .NET6 addresses this issue. Let’s rewrite the previous example in .NET6 with a new template.

Just 4 lines of code for our first endpoint. Single file. This is new .NET minimal API!

Back to my friend’s question — “Do you need all of this stuff just to shorten URL?”

No.
I can do better.

✂️ 2. Refactored URL shortener example

A while back, I wrote a post on how to write URL shortener in .NET5?, but I never could have imagined that I would be able to write .NET shortener in 26 lines of code and a single file.

Note: we actually have two files — we will get to the bottom of that in the fifth section, bear with me.

Refactored code:

You can find the previous URL shortener example in this github repository. There is nothing minimal about the codebase.

If we compare the old code to our minimal shortener, we will see the hidden complexity of the minimal API framework right away.

We start from scratch in the minimal API template and only introduce the dependencies we need. We can concentrate on the important stuff — the code for the requested feature.

Let’s analyse the code and see what new things come with .NET6 that you could start implementing in your services.

⚙️ 3. Adding Dependencies

My service needs a database, so I’m adding a dependency to LiteDB.

dotnet add package LiteDB

Usually, we would go to Startup.cs and set up our dependency. Since we don’t have one, the way to go is shown below on line 2. Same code, in a different position.

🔗 4. Adding an Endpoint

All the methods we need are in the app — or should I say framework?

  • MapGet(pattern, handler)
  • MapPost(pattern, handler)
  • MapPut(pattern, handler)
  • MapDelete(pattern, handler)

Check how to implement POST method and GET method in the example below.

The first parameter is the route pattern, and the second parameter is the handler. The handler is delegate executed when the endpoint is matched.

Url object is record, also something new in .NET6. It could be a class as well, but I just wanted to shred couple of lines of code to get those 26 magic lines.

Data that our POST method (body of req) needs to contain is
defined by the record. (It is enough to send longURL, id will be set automatically by our db)

We have our database in the list of services that our app uses. The next step is to inject it into the endpoint. The delegate needs to have our database context to add data from the client to the database.

In the end, set up your service address and port.
And you are done!

app.Run("http://localhost:4000");

🙋 5. Where are using statements?

Global using statements is another feature I am happy with.

Do you remember having something like this on top of every file in your project?

using System;
using System.Reflection;
using System.Linq;
using System.Net.Http;
using System.Linq;

Implicit usings are hidden in an auto-generated file inside the obj folder. That file declares global using statements behind the scenes. If you go to the project folder then to obj/Debug/net6.0, you will find a file titled ”{ProjectName}.GlobalUsings.g.cs”.

Open this file, and see the content:

Since this is an auto-generated file, we can’t edit it here.

In our minimal shortener, we have two packages (LiteDB, Hashids.net) that we depend upon, and we would need to place using statements in Program.cs to use code from these packages.

Instead, let’s manually create a file that will hold our global using statements. This way, we keep our Program.cs free from all using statements.

It might be overkill in this particular example, but imagine adding more dependencies. It is a good option for keeping code clean.

🎊 So, is it possible? Of course! 🎊

Most of the time, we don’t need all the ceremony that we got with previous .NET Web API templates.

Now, there’s the option to start from scratch and only add the stuff we really need. Missing MVC Controllers? No problem, add them later. Need Authentication? Same thing.

The template code has fewer files and a more intuitive setup for newcomers in the .NET world — this is probably one of the best benefits of this framework. I am really looking forward to seeing what future updates bring along.

If you enjoyed following along and building your own URL shortener in .NET6, keep an eye out for this blog!

In the next article, we will place this minimal URL Shortener in Docker and explore another essential piece of the tech stack.

--

--

Dino Lozina
Infobip Developers

Engineer with strong programming background. At the moment I am working on web technologies in .NET world. My point of interests are WebAssembly and API design.