본문 바로가기
Back-end/nest.js

Nest.js : Controller url 오류 (컨트롤러 경로 오류, 에러)

by hsloth 2023. 6. 19.

 

Nest.js 서버를 키고 요청을 날리다가 안되는 요청이 있어서 왜이러지? 하고 거의 1시간 반을 찾아봤다.

결국 이런 저런 삽질 끝에...

 

Controller의 url경로 때문이라는 것을 깨닫게 되었다.

 

자, Controller의 다음 두가지 함수가 있다.

@Controller('user')
export class UserController {
	...
    @Get(':id')
    async getUser(@Param('id') id: number) {
    	return id;
    }
    
    @Get('list')
    async getUserList() {
    	const userList = [user1, user2, ...]
    	return userList;
    }
}

내가 아무리 /user/list 경로에 Get 요청을 보내도... getUserList함수가 타지지 않는다.

이 경우, nest.js는 위에서부터 함수를 읽기 때문에 list를 param으로 여기고, getUser함수를 먼저 타버리게 된다...

:id에 list가 들어가서 id = 'list'가 되어버리는 것이다.

그래서 id가 number인데 list는 string이라고 content-type이 application/json 이 아니라고 터미널에서 뭐라고 할 것이다 ㅎㅎ

 

다음은 swagger의 response에서 뜬 오류이다.

{
  "statusCode": 400,
  "message": "Value of the URL parameter \"id\" is not a number.",
  "error": "Bad Request"
}

 

다음은 터미널에서 뜬 오류이다.

WARN [ExpressAdapter] Content-Type doesn't match Reply body, 
you might need a custom ExceptionFilter for non-JSON responses

 

그러면 이제 해결 방법을 생각해보자.

  1. param의 위치에 따라 함수의 위치를 나눈다.
    • Param이 경로의 첫번째에 들어가는 함수를 맨 아래로
    • Param이 경로의 두번째에 들어가는 함수를 바로 그 위로
    • Param이 경로의 세번째에 들어가는 함수를 또 그 위로
  2. param을 고려하여 다른 함수들의 url 경로를 정한다.

 

1번을 예로 들어서 함수의 순서를 정하자면 이렇게 되시겠다...

@Get('hi')
async e()

@Get('hi/bye')
async d()

@Get('hi/bye/:count')
async c()

@Get('hi/:room')
async b()

@Get(':id/:room')
async ab()

@Get(':id')
async a()

e()를 호출하려면 e가 a()보다 위에 있어야 한다.

d()를 호출하려면 d가 b()보다 위에 있어야 한다.

b()를 호출하려면 b가 ab()보다 위에 있어야 한다.

 

 

 

 

2번을 예로들면 아래와 같다.

@Get(':id')
async a()

@Get('list')
async b()

// 아래와 같이 안겹치게 바꾸자.
@Get(':id')
async a()

@Get('list/all')
async b()

 

1번은 너무 머리아플것 같은데,

2번은 보자마자 '아! 이거 param 때문에 경로 바꿔야지!' 라고 떠오를 것 같지가 않다.

 

 

 

여러분들이 하시는 방법 중에 좋은 방법이 있으면 공유해주셨으면 합니다...

포스팅 읽어주셔서 감사합니다!