92-Nodejs Course 2023: Restful Routes: Listing Records
Tags: node, typescript, mongodb, fastify
Published: 2022-12-09 11:02:29

---
title: 92-Nodejs Course 2023: Restful Routes: Listing Records
published: true
description: 
series: Nodejs Course 2023
tags: nodejs, typescript, mongodb, fastify
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n2v35r25u0h411vfh4g1.png
# Use a ratio of 100:42 for best results.
---

We saw in our previous article how we implemented our `Restful` class, now we'll implement the `list` method.

## 📝 Workflow

The point here is the child restful class `i.e RestfulUser class` we need to define inside it the base model that will perform our database operations, so firstly we need to define the base model in the `Restful` class.

OK what next? next we'll use that model in the base class to list all the records.

Also, we can pass a `query` object to the `list` method to filter the records from the request using `request.all()` method.

As we already have implemented our pagination, we can also return the pagination data in the response.

## 🚀 Implementation

Navigate to our `Restful` class and add the following code:

```ts
// src/core/router/restful.ts
import { Model } from "core/database";
import { Request, Response } from "core/http";
import { RouteResource } from "core/router/types";

export default class Restful implements RouteResource {
  /**
   * Base model
   */
  protected model?: Model;

  /**
   * List records
   */
  public async list(request: Request, response: Response) {
    const records = await this.model?.list(request.all()) || [];

    return response.success({
      records,
    });
  }
// ...
```

Once you write down this and you'll find that Typescript Compiler is screaming at you, you can not use `list` method directly from the `Model` class, thus we need to use `ChildModel` type instead.

But we didn't export the model types file, so let's do this first

```ts
// core/database/model/index.ts
export { default as Model } from "./model";
export * from "./types";
```

Now we can import the `ChildModel` type from the `database` directly.

```ts
// src/core/router/restful.ts
import { Model, ChildModel } from "core/database";
import { Request, Response } from "core/http";
import { RouteResource } from "core/router/types";

export default class Restful implements RouteResource {
  /**
   * Base model
   */
  protected model?: ChildModel;

  /**
   * List records
   */
  public async list(request: Request, response: Response) {
    const records = await this.model?.list(request.all()) || [];

    return response.success({
      records,
    });
  }
// ...
```

This is good, but if you remember that the `ChildModel` is a generic type, so we need to pass the model type to it, we can pass the type using our `Restful` class declaration.

```ts
// src/core/router/restful.ts
import { Model, ChildModel } from "core/database";
import { Request, Response } from "core/http";
import { RouteResource } from "core/router/types";

export default class Restful<T> implements RouteResource {
  /**
   * Base model
   */
  protected model?: ChildModel<T>;

  /**
   * List records
   */
  public async list(request: Request, response: Response) {
    const records = await this.model?.list(request.all()) || [];

    return response.success({
      records,
    });
  }
// ...
```

Now we're good, do you want to make it more fancy? let's make the `T` type extends the `Model` class, so we can use the `list` method directly from the `T` type.

```ts
// src/core/router/restful.ts
import { Model, ChildModel } from "core/database";
import { Request, Response } from "core/http";
import { RouteResource } from "core/router/types";

export default class Restful<T extends Model> implements RouteResource {
  /**
   * Base model
   */
  protected model?: ChildModel<T>;

  /**
   * List records
   */
  public async list(request: Request, response: Response) {
    const records = await this.model?.list(request.all()) || [];

    return response.success({
      records,
    });
  }
// ...
```

Now that's an elegant code

The final question remains here is why i added `|| []` at the end? well, because maybe you would forget to pass the model to the `Restful` class, so we need to make sure that the `records` variable is an array.

## 📝 Testing

Now let's put this code into test, let's try it in our `RestfulUser` class

```ts
// src/app/user/controller/restful-user.ts
import { Request, Response } from "core/http";
import Restful from "core/router/restful";
import { RouteResource } from "core/router/types";
import User from "../models/user";

// Note that we passed the model 👇🏻 type as a generic type to the Restful class
class RestfulUser extends Restful<User> implements RouteResource {
  /**
   * Base model
   */
  protected model = User;

  /**
   * Get single record
   */
  public async get(request: Request, response: Response) {
    //
  }

  /**
   * Create record
   */
  public async create(request: Request) {
    //
  }

  /**
   * Update record
   */
  public async update(request: Request, response: Response) {
    //
  }

  /**
   * Delete record
   */
  public async delete(request: Request, response: Response) {
    //
  }

  /**
   * Patch record
   */
  public async patch(request: Request, response: Response) {
    //
  }
}

const restfulUser = new RestfulUser();

export default restfulUser;
```

Now we can call our beloved route `/users` directly, no more code to be added, we defined the model and also defined the model type, so we're good to go now.

The other good part here, is we can use also the filter directly, just try `/users?name=hasan` or whatever value you add, and you'll see that the filter is working!

## 🎨 Conclusion

We just did some pretty good things here, learnt how to use generics with good practical example, also learnt how to implement the list method so we don't have to write it to every controller.

## ☕♨️ Buy me a Coffee ♨️☕

If you enjoy my articles and see it useful to you, you may [buy me a coffee](https://www.paypal.com/paypalme/hassanzohdy), it will help me to keep going and keep creating more content.

## 🚀 Project Repository

You can find the latest updates of this project on [Github](https://github.com/hassanzohdy/nodejs-2023)

## 😍 Join our community

Join our community on [Discord](https://discord.gg/pb2vmdfhGf) to get help and support (Node Js 2023 Channel).

## 🎞️ Video Course (Arabic Voice)

If you want to learn this course in video format, you can find it on [Youtube](https://www.youtube.com/playlist?list=PLGO8ntvxgiZMJc7RN2lIq9WmMOlWZGzmz), the course is in Arabic language.

## 📚 Bonus Content 📚

You may have a look at these articles, it will definitely boost your knowledge and productivity.

General Topics

- [Event Driven Architecture: A Practical Guide in Javascript](https://dev.to/hassanzohdy/event-driven-architecture-the-best-paradigm-that-i-love-to-work-with-in-javascript-and-node-js-1gnk)
- [Best Practices For Case Styles: Camel, Pascal, Snake, and Kebab Case In Node And Javascript](https://dev.to/hassanzohdy/best-practices-for-case-styles-camel-pascal-snake-and-kebab-case-in-node-and-javascript-55oi)
- [After 6 years of practicing MongoDB, Here are my thoughts on MongoDB vs MySQL
](https://dev.to/hassanzohdy/after-6-years-of-practicing-mongodb-here-are-my-thoughts-on-mongodb-vs-mysql-574b)

Packages & Libraries

- [Collections: Your ultimate Javascript Arrays Manager](https://dev.to/hassanzohdy/collections-your-ultimate-javascript-array-handler-3o15)
- [Supportive Is: an elegant utility to check types of values in JavaScript](https://dev.to/hassanzohdy/supportive-is-an-elegant-utility-to-check-types-of-values-in-javascript-1b3e)
- [Localization: An agnostic i18n package to manage localization in your project](https://dev.to/hassanzohdy/mongez-localization-the-simplest-way-to-translate-your-website-regardless-your-favorite-framework-4gi3)

 React Js Packages

- [useFetcher: easiest way to fetch data in React Js](https://dev.to/hassanzohdy/usefetcher-the-easiest-way-to-fetch-data-in-react-45o9)

Courses (Articles)

- [OOP In JS And TS From The Very Beginning](https://dev.to/hassanzohdy/jsts-oop-course-1-introduction-2ld)
- [ES6++: The Ultimate Guide to ES6 and Beyond](https://dev.to/hassanzohdy/es6-1-introduction-h3e)
- [React Js: Let"s Create File Manager With React Js and Node Js](https://dev.to/hassanzohdy/lets-create-a-file-manager-from-scratch-with-react-and-typescript-chapter-i-a-good-way-to-expand-your-experience-5g4k)