How to Access Query Strings in Minimal APIs
Tags: aspnetcore, dotnet6, csharp, minimalapis
Published: 2022-07-17 22:46:38

---
title: How to Access Query Strings in Minimal APIs
published: true
date: 2022-04-04 00:00:00 UTC
tags: 
  - aspnetcore
  - dotnet6
  - csharp
  - minimalapis
canonical_url: https://wildermuth.com/2022/04/04/query-strings-optional-arguments-minimal-apis-aspnetcore/
cover_image: https://wilderminds.blob.core.windows.net/img/2022/04/04/pexels-tim-samuel-5835580.jpg
---

I love that this job allows me to learn new stuff every day. In this case, I was building a simple API to use for some upcoming [Pluralsight](https://shawnl.ink/psauthor) courses. I wanted to use Minimal APIs to expose some data for an old dataset from [FiveThirtyEight](https://data.fivethirtyeight.com/) on Bechdel Tests for Films. While I was adding paging, I got confused.

So, I started with a minimal API for getting all the films like so:

```
app.MapGet("api/films", async (BechdelDataService ds) =>
{

  if (ds is null) return Results.BadRequest();
  FilmResult data = await ds.LoadAllFilmsAsync();
  if (data.Results is null) return Results.NotFound();

  return Results.Ok(data);

}).WithTags("By Film").Produces(200).ProducesProblem(404);

```

Pretty simple Minimal API to get some data (my BechdelDataService is just a repository-like class). When I added paging, I wanted to use the typical Web API trick of using optional parameters:

```
app.MapGet("api/films", async (BechdelDataService ds, 
  int page = 1, 
  int pageSize = 50) =>
{
...
}).WithTags("By Film").Produces(200).ProducesProblem(404);

```

To my surprise this didn’t work. What I expected was that if I used a query string, it would bind to the extra parameters by name:

```
/api/films?page=1
/api/films

```

In this case, these should be the same. What is going on. At first I dove into seeing why Minimal APIs didn’t support this. I didn’t see much about it, I saw options to read the query strings manually:

```
app.MapGet("api/films", async (
    HttpRequest request, 
    BechdelDataService ds) =>
{
  var page = request.Query["page"] ?? 1;
  var size = request.Query["pageSize"] ?? 50;

...

    
}).WithTags("By Film").Produces(200).ProducesProblem(404);

```

This works, but I found it clunky. I wanted binding to work. I saw some examples that broke out the lambda to a method:

```
app.MapGet("api/films", GetAllFilms);

async Task<IResult> GetAllFilms(BechdelDataService ds, 
  int page = 1, 
  int pageSize = 50)
{
    ...
}

```

This works, so the problem wasn’t with Minimal APIs, the problem is that Lambdas do not support default values (since you’re passing in a lambda, the spec assumes that you’ll supply all values).

So this is a fix? I don’t like the messiness of breaking it out into separate methods. So how do we fix it? Let’s use nullable values:

```
app.MapGet("api/films", async (BechdelDataService ds, 
  int? page, 
  int? pageSize) =>
{
  if (ds is null) return Results.BadRequest();
  int pageNumber = page ?? 1;
  int pagerTake = pageSize ?? 50;

  FilmResult data = await ds.LoadAllFilmsAsync(pageNumber, pagerTake);
  if (data.Results is null) return Results.NotFound();

  return Results.Ok(data);

    
}).WithTags("By Film").Produces(200).ProducesProblem(404);

```

By supplying the values as nullable types (int?), we have to do our own defaulting, but I think it’s acceptable. One note here, is that I’m defining the types to non-nullable types to make my calls to the data service easier, but this isn’t necessary.

So, was I the only one who didn’t know that default values weren’t supported in lambda’s?

[![Creative Commons License](http://i.creativecommons.org/l/by-nc-nd/3.0/88x31.png)](http://creativecommons.org/licenses/by-nc-nd/3.0/)

 This work by [Shawn Wildermuth](http://wildermuth.com) is licensed under a [Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License](http://creativecommons.org/licenses/by-nc-nd/3.0/).  
 Based on a work at [wildermuth.com](http://wildermuth.com).

* * *

If you liked this article, see Shawn's courses on [Pluralsight](http://shawnw.me/pscourses).