Back-end/nest.js

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

hsloth 2023. 6. 19. 01:06

 

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 때문에 경로 바꿔야지!' 라고 떠오를 것 같지가 않다.

 

 

 

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

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