# REST API - Use EF Core to create a paged endpoint quickly

There is often the question from my colleagues about how to do a quick paged requests on records without typing a lot of SQL code in stored procedure or in code by filtering a collection of records.

The answer for this question comes with EF Core but Entity Framework in general.

## Create the API project

1. Open Visual Studio 2022
    
2. Create a new project (File / New / Project...)
    
3. Choose ASP.Net Core Web API (native AOT) to create a minimal API project
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708297635419/b6e20f2e-68b5-426d-8f4c-7d405de0b44d.png align="center")

1. I let you named and store it wherever you want
    
2. The project is now created. Now go on the endpoint creation.
    

## Create the list of records

1. Add the nuget package **Swashbuckle.AspNetCore** to the project.
    
2. Change the **Program** method by this one below
    

```csharp
public class Program
{
    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateSlimBuilder(args);

        builder.Services.AddEndpointsApiExplorer();
        builder.Services.AddSwaggerGen();
        
        builder.Services.ConfigureHttpJsonOptions(options =>
        {
            options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default);
        });

        var app = builder.Build();
        app.UseSwagger();
        app.UseSwaggerUI();

        var sampleTodos = new Todo[] {
            new(1, "Walk the dog"),
            new(2, "Do the dishes", DateOnly.FromDateTime(DateTime.Now)),
            new(3, "Do the laundry", DateOnly.FromDateTime(DateTime.Now.AddDays(1))),
            new(4, "Clean the bathroom"),
            new(5, "Clean the car", DateOnly.FromDateTime(DateTime.Now.AddDays(2))),
            new(6, "Buy vegetables to the grocery", DateOnly.FromDateTime(DateTime.Now.AddDays(1))),
            new(7, "Buy clothes for the wedding", DateOnly.FromDateTime(DateTime.Now.AddDays(15))),
            new(8, "Clean the bedroom"),
            new(9, "Mooing the lawn", DateOnly.FromDateTime(DateTime.Now.AddDays(2))),
            new(10, "Cut the rose bushes", DateOnly.FromDateTime(DateTime.Now.AddDays(2))),
            new(11, "Cut the wood to prepare the winter"),
        };

        var todosApi = app.MapGroup("/todos");
        todosApi.MapGet("/", () => sampleTodos);
        todosApi.MapGet("/{id}", (int id) => sampleTodos.FirstOrDefault(a => a.Id == id) is { } todo ? Results.Ok(todo) : Results.NotFound());
        
        app.Run();
    }
}
```

1. Now we have a little collection of records with a Swagger user-interface to display the API
    
2. In the .csproj, add the **JsonSerializerIsReflectionEnabledByDefault** tag to let Swagger auto-discover and serialize the objects
    

```xml
<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    ...
    <PublishAot>true</PublishAot>
    <JsonSerializerIsReflectionEnabledByDefault>true</JsonSerializerIsReflectionEnabledByDefault>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
  </ItemGroup>

</Project>
```

1. Open the **launchSettings.json** file in the *Properties* folder and change the *launchUrl* to **swagger**
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1708298206333/696b1566-1cca-4233-8da4-9c1e64496a4b.png align="left")
    

```json
{
  "$schema": "http://json.schemastore.org/launchsettings.json",
  "profiles": {
    "http": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "launchBrowser": true,
      "launchUrl": "swagger",
      "applicationUrl": "http://localhost:5241",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}
```

1. Launch the application
    

## Create the endpoint for paged list of records

In the **Program** method, under the declared endpoints, add this line.

```csharp
todosApi.MapGet("/page/{page}", (int page) => sampleTodos.Skip((page - 1) * 5).Take(5).ToArray() is  { } todos ? Results.Ok(todos) : Results.NotFound() );
```

> Wow, only this code !

Yes, let me detailed what we have done here !

1. We add a new endpoint answering to the URL *https://&lt;hosturl:port&gt;/todos/page/&lt;pageid&gt;*
    
2. We declare a new function with only the parameter page and where is role is to return the records of the requested page identifier
    
3. The body of the function, the real subject here :
    

```csharp
sampleTodos.Skip((page - 1) * 5).Take(5).ToArray()
```

Here, we will consider a page will contain only 5 records

Thanks to Entity Framework we can call the function *Skip()* on the collection **sampleTodos** to avoid the selection of the X first records of the collection. X is the number of records of the previous page we want to skip.

And just after skipping the first records, we call the function Take() on the result to only get the 5 records of the page. This function will take 5 records at maximum so even a page have less records it will works.

Thank you Entity Framework 😊

1. Launch the application and try yourself with the new endpoint.
    

---

## **Let's Connect!**

Hi, I'm Yoann. I work as a full-stack developer, solution architect.

If you enjoyed this article, you might enjoy my other content, too.

**Github:** [yblossier](https://github.com/yblossier)

**LinkedIn:** [**/in/yoannblossier**](https://linkedin.com/in/yoannblossier)

**Buy Me A Coffee:** [A special thank you for your support](https://www.buymeacoffee.com/yoannblossier) **🍵**

Thank you for joining me today.

Yoann
