DEV Community

Cover image for Write a URL Shortener in 26 Lines of Code with .NET Minimal APIs
Dino Lozina for Infobip

Posted on • Originally published at Medium

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

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 APIs

”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 .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.

4 lines of code for our first endpoint and a 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 create a URL shortener in .NET5), but I never imagined that I'd be able to rewrite it 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 database, so I'm adding a dependency to LiteDB.

dotnet add package LiteDB
Enter fullscreen mode Exit fullscreen mode

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, 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 route pattern, the second parameter is handler. The handler is delegate executed when endpoint is matched.

The 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");
Enter fullscreen mode Exit fullscreen mode

🙋 5. Where are using statements?

Global using statements is another feature I am happy with. Do you remember 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;
Enter fullscreen mode Exit fullscreen mode

Implicit usings are hidden in auto generated file inside your obj folder. That file declares global using statements behind the scenes. If you go to project folder then go 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 autogenerated file, we can’t edit it here.
In our minimal shortener we have two packages (LiteDB, Hashids.net) that we depend upon, and we will actually need to place using statements in our Program.cs to use code from 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 webapi templates.

Now we have the option to start from scratch and add only stuff that 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.

Top comments (1)

Collapse
 
onlinemsr profile image
Raja MSR

It shows the .NET minimal APIs capabilities.

// var tempId = id[0]; // - I am not clear on this line. What it is doing?