Skip to content

Differentiate 2 routes of a controller (NestJS)

EDIT: When I move the @Get(‘/random’) above the 2 other routes, it’s working… Weird

I’m doing a NestJS server that just get some routes of the Breaking Bad API and displays the JSON in the routes of the server,

I want to create 3 routes :

  • 1 that returns a JSON of all characters of the show (/characters/all)
  • 1 that returns a JSON of a single character of the show (/characters/:id)
  • 1 that returns a JSON of a random character of the show (/character/random)

The 2 firsts routes are working, but I can’t get the last one, I get an error 500 that says Error: Request failed with status code 500 and the url targeted is ‘https://www.breakingbadapi.com/api/characters/random’, I d on’t know why it’s ‘characters’ and not ‘character’

Here is my code :

characters.controller.ts

import { Controller, Get, Post, Body, Param } from '@nestjs/common';
import { CharactersService } from './characters.service';

@Controller('characters')
export class CharactersController {
    constructor(private readonly charactersService: CharactersService) {}

    @Get('/all')
    getAll() {
        return this.charactersService.getAll();
    }

    @Get(':id')
    getOne(@Param('id') id: string) {
        return this.charactersService.getOne(id);
    }

    @Get('/random')
    getRandom() {
        return this.charactersService.getRandom();
    }
}

characters.service.ts

import axios from "axios";

import { Injectable } from '@nestjs/common';

@Injectable()
export class CharactersService {
    getAll() {
      return axios.get(`${process.env.ENDPOINT_BASE_URL}/characters`, {
        params: {
          limit: null,
          offset: null,
          name: ""
        }
      }).then(function (response) {
          return response.data;
        })
        .catch(function (error) {
          console.log(error);
        });
    }

    getOne(id: string) {
      return axios.get(`${process.env.ENDPOINT_BASE_URL}/characters/${id}`).then(function (response) {
        return response.data;
      })
      .catch(function (error) {
        console.log(error);
      });
    }

    getRandom() {
      return axios.get(`${process.env.ENDPOINT_BASE_URL}/character/random`).then(function (response) {
        return response.data;
      })
      .catch(function (error) {
        console.log(error);
      });
    }
}

.env

ENDPOINT_BASE_URL=https://www.breakingbadapi.com/api

Answer

Order of routes defined matters very much in a Nest server. By having the @Get(':id') before @Get('/random') you’re cutting off access to /random because the underlying HTTP engine will consider the string "random" as an id for ':id'.

I don’t know why it’s ‘characters’ and not ‘character’

As mentioned above, the random gets pulled in to be an id and not a route itself. Moving the @Get('/random') route and handler to above @Get(':id') should fix that for you.