Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

An example web app based on the new feature in .NET 8 | minimal web API in ASP.NET 8

License

NotificationsYou must be signed in to change notification settings

dotnet-labs/Minimal-URL-Shortener

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

The solution is updated to .NET 8

Buy Me a Coffee at ko-fi.com

As announced in the.NET 6 Preview 4 blog, .NET 6 will release an improvement to ASP.NET Core: minimal APIs for hosting and routing in web applications. With these streamlined APIs, we can build microservices and small HTTP APIs with much less ceremony.

In this article, we will first briefly describe the minimal APIs feature in .NET 6. To further demonstrate its use case, we then create a URL shortener web app and containerize it using Docker.

Minimal APIs

To try out a minimal API, we can create an empty web app using the following command.

dotnet new web

This command creates a web project with just a singleProgram.cs file, which has the following content.

usingSystem;usingMicrosoft.AspNetCore.Builder;usingMicrosoft.Extensions.Hosting;varbuilder=WebApplication.CreateBuilder(args);awaitusingvarapp=builder.Build();if(app.Environment.IsDevelopment()){app.UseDeveloperExceptionPage();}app.MapGet("/",(Func<string>)(()=>"Hello World!"));awaitapp.RunAsync();

TheProgram.cs file is written in the style oftop-level program, which gets rid ofclass Program and theMain() method thus decreases code clutters. In the code above, the first few lines create a web host, then line 13 defines a route in the routing table using theMapGet method. We can continue to build more APIs usingMapGet,MapPost, and similar methods.

The API composition is quite different from the traditional API Controller or MVC style. The minimal APIs have really pushed the number of lines of code to an extreme. If our APIs are simply doing some non-essential computation or CRUD operations, then the minimal APIs can reduce a lot of overhead.

If we run the app, we will see the string "Hello World!" on the homepage. That's it! With only a few lines of code, we now have a fully functioning HTTP API.

URL Shortener

For demo purposes, we will create a URL Shortener web app. The app provides a form that allows users to enter a URL to get its shortened version. The app persists the an entry with the original URL and its shortened version. Therefore, the app is able to redirect a shortened URL to its original address. The following screen recording demonstrates the features to be implemented.

url shortener

1. Creating an API to Shorten a URL

In this app, we are going to store the map entries between shortened and original URLs in a local database. A NoSQL database is suitable for this scenario since this app doesn't have complex data relationships. If we don't consider the scalability, thenLiteDB is a good database candidate. If you haven't heard about it, LiteDB is a small, fast and lightweight .NET NoSQL embedded database, and we can think LiteDB as a combination of SQLite and MongoDB.

After install the LiteDB NuGet package, we can register theLiteDatabase in the Dependency Injection (DI) container as follows.

varbuilder=WebApplication.CreateBuilder(args);builder.Services.AddSingleton<ILiteDatabase,LiteDatabase>(_=>newLiteDatabase("short-links.db"));awaitusingvarapp=builder.Build();

Then we can create a POST API which takes in a request body with a URL and returns a JSON object contains the shortened URL.

app.MapPost("/url",ShortenerDelegate);staticasyncTaskShortenerDelegate(HttpContexthttpContext){varrequest=awaithttpContext.Request.ReadFromJsonAsync<UrlDto>();if(!Uri.TryCreate(request.Url,UriKind.Absolute,outvarinputUri)){httpContext.Response.StatusCode=StatusCodes.Status400BadRequest;awaithttpContext.Response.WriteAsync("URL is invalid.");return;}varliteDb=httpContext.RequestServices.GetRequiredService<ILiteDatabase>();varlinks=liteDb.GetCollection<ShortUrl>(BsonAutoId.Int32);varentry=newShortUrl(inputUri);links.Insert(entry);varresult=$"{httpContext.Request.Scheme}://{httpContext.Request.Host}/{entry.UrlChunk}";awaithttpContext.Response.WriteAsJsonAsync(new{url=result});}publicclassUrlDto{publicstringUrl{get;set;}}publicclassShortUrl{publicintId{get;protectedset;}publicstringUrl{get;protectedset;}publicstringUrlChunk=>WebEncoders.Base64UrlEncode(BitConverter.GetBytes(Id));publicShortUrl(Uriurl){Url=url.ToString();}}

In the code above, line 1 defines the route/url for the POST API, and hooks it up with a request delegateShortenerDelegate to handle HTTP requests. Inside theShortenerDelegate method, we first parse the request body to get the URL and validate its format. Then we resolve theILiteDatabase service from the DI container, and insert an entry into the database. In the end, the delegate method returns the shortened URL as a JSON object.

We model the short URLs as a classShortUrl, where theUrl property represents the original URL and theId property is auto generated when inserting into the NoSQL database. TheId property ensures the uniqueness of each URL in the local database. In order to generate a short URL chunk, we use theWebEncoders.Base64UrlEncode() method to convert from anId, an integer, to theUrlChunk, a string. Note that you should reference ausing Microsoft.AspNetCore.WebUtilities; statement to get the method's namespace.

For example, whenId = 1, theUrlChunk isAQAAAA; whenId = 2, theUrlChunk isAgAAAA; and so on. In the next section, we will convert theUrlChunk back to theId to get its originalUrl from the local database.

With that, we now have an API endpoint which accepts HTTP POST requests with a JSON body containing a URL string, and returns a JSON object containing a shortened URL string. We can test the API endpoint using Postman.

postman

2. Creating an API to Redirect URLs

Now we are going to support another feature for redirecting short URLs to their original URLs. This API has to cover lots of variations, thus the easiest way to catch all URLs is to use theMapFallback() method. Also note that we should place this method after all other routes so that those deterministic routes could be matched first.

app.MapFallback(RedirectDelegate);staticasyncTaskRedirectDelegate(HttpContexthttpContext){vardb=httpContext.RequestServices.GetRequiredService<ILiteDatabase>();varcollection=db.GetCollection<ShortUrl>();varpath=httpContext.Request.Path.ToUriComponent().Trim('/');varid=BitConverter.ToInt32(WebEncoders.Base64UrlDecode(path));varentry=collection.Find(p=>p.Id==id).FirstOrDefault();httpContext.Response.Redirect(entry?.Url??"/");awaitTask.CompletedTask;}

The fallback route is hooked to aRedirectDelegate. In this delegate method, we first resolve theILiteDatabase from the DI container and search the short URL from the database. If found, then the API redirects the page to its original URL. Otherwise, the API redirects the page to the app's homepage.

3. Creating an API to Serve a Static HTML Page

For this app, we only need a simple HTML page to allow end users to send HTTP requests using an input and a button. Thus we are going to create anindex.html file and write the user interface there. The web page looks like the following screenshot.

Note that theindex.html file needs to be included in this project.

Once theindex.html file is ready, we can register the route as follows.

app.MapGet("/", ctx=>{ctx.Response.ContentType="text/html";returnctx.Response.SendFileAsync("index.html");});

Now we have completed this web application. You can test it out if you have the latest .NET 6 preview version installed. Or we can try out the application using Docker.

4. Containerizing Our App

Docker allows us to containerize our applications thus easy to deploy, maintain, and scale. I have prepared a Dockerfile for this app.

docker run -it mcr.microsoft.com/dotnet/sdk:6.0-alpine sh/# dotnet --info/# dotnet new web
docker build -t url-shortener-net6.docker run -it --rm -p 8080:80 url-shortener-net6# then visit http://localhost:8080/

License

Feel free to use the code in this repository as it is under MIT license.

Buy Me a Coffee at ko-fi.com

About

An example web app based on the new feature in .NET 8 | minimal web API in ASP.NET 8

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

    Packages

    No packages published

    [8]ページ先頭

    ©2009-2025 Movatter.jp