# 시작
Nextjs에 익숙해지기 위해서 유튜브에서 Nextjs Tutorial 영상을 따라 공부하면서 알게 되는 것들을 적을 것이다.
따라한 유튜브 영상은 아래 링크이다.
넥스트 튜토리얼 4차시 API Routes와 Database에 대해서 다룬다.
# 정리
# 4
화면 왼쪽에 유저의 프로필이 보여지고 오른쪽에 그 유저가 가지고 있는 차들의 목록을 가져올 수 있다. 이것을 구현하기 위해서 API를 만들어볼 것이다. API를 만들어보기 전에 API에 대해서 알아보았다. API endpoint나 GET, POST 메소드들을 정확히 알고 있지 않아서 다시 조사해보았다.
아래 링크를 참고하여 이해하였다.
- API란?
API (Application Programming Interface, 응용 프로그래밍 인터페이스)는 응용 프로그램에서 사용할 수 있도록, 운영 체제나 프로그래밍 언어가 제공하는 기능을 제어할 수 있게 만든 인터페이스를 뜻한다. 주로 파일 제어, 창 제어, 화상 처리, 문자 제어 등을 위한 인터페이스를 제공한다. - 위키백과
https://velog.io/@kho5420/Web-API-%EA%B7%B8%EB%A6%AC%EA%B3%A0-EndPoint
우리는 웹사이트에서 API를 만들어 사용하므로 정확히는 REST API라는 API를 이해하고 있어야 한다.
https://velog.io/@kho5420/Web-API-%EA%B7%B8%EB%A6%AC%EA%B3%A0-EndPoint
REST API는 REST로 서비스 API를 구현한 것을 말하는데 REST란 무엇인지 이해하고 있어야 한다.
- REST의 4가지 속성
- 서버에 있는 모든 Resource는 각 Resource마다 Client가 바로 접근할 수 있는 고유 URL이 존재한다.
- 모든 요청은 Client가 요청할 때마다 필요한 정보를 주기 때문에 서버에서는 세션 정보를 보관할 필요가 없습니다. 그렇기 때문에 서비스에 자유도가 높아지고 유연한 아키텍쳐 적응이 가능하다.
- HTTP 메소드를 사용한다. 즉, 모든 Resource는 일반적으로 HTTP 인터페이스인 GET, POST, PUT, DELETE 4개의 메소드로 접근되어야 한다.
- 서비스 내에 하나의 Resource가 주변에 연관된 Resource들과 연결되어 표현이 되어야 한다.
- REST의 구성요소는 Resource, Method, Message 세 가지로 구성되어있다.
- REST에서 자원(Resource)에 접근할 때 URL로 하게 됩니다.
- URL은 Resource의 위치를 나타내는 일종의 식별자입니다.
- Endpoint
https://velog.io/@kho5420/Web-API-%EA%B7%B8%EB%A6%AC%EA%B3%A0-EndPoint
메소드가 GET으로 동일하더라도 다른 요청을 하게끔 구별하는 것이 바로 Endpoint다. Endpoint는 API가 서버에서 Resource에 접근할 수 있도록 해주는 URL이다. 여기서는 http://api.domain.com/books/1나 http://api.domain.com/books 이다.
- 우리가 API를 통해 받아오는 것은 서버의 Resource가 아니다. 서버가 보내준 JSON은 단지 데이터베이스에 저장되어있는 원본 데이터 리소스의 현재 상태를 표현한 것이다.
- 이번에 필요한 API들은 아래와 같다.
- 진행 순서
- 이 영상에서 SQL을 사용하는 이유?
- API를 직접 만들어본다. vscode에서 프로젝트 pages/api/vehicles.tsx를 생성하고 아래의 코드를 입력한다.
if문으로 메소드가 GET이 아닌 경우 internal server error가 발생하도록 작성했다. 제대로 작동하는지는 브라우저를 켜서 개발자 도구에 콘솔을 입력하여 확인할 수 있다.
크롬 개발자 도구 콘솔
또한, 크롬 개발자 도구의 Network 탭을 들어가면 반환해주는 메시지를 확인해볼 수 있다.
크롬 개발자 도구 Network
반면에, GET 메소드로 요청하면 정상적으로 동작한다.
크롬 개발자 도구 콘솔
- 지난 시간에 배운 동적 라우팅을 이용해서 req.query.id를 출력시켜본다.
[id].ts로 URL로 들어온 파라미터는 id에 들어와서 json 객체에서 res.query.id로 확인할 수 있다.
사람들마다 보유하고 있는 자동차들을 보여주기 위해 pages/person/[id]/index.ts와 vehicles.ts를 생성했다.
실제로 브라우저에서 localhost:3000/api/person/555라고 했을 때 index.ts에 의해서
{ byId: 555, message: "getPersonById" } 라는 값을 보여준다.
그리고 localhost:3000/api/person/555/vehicles를 입력하면 555라는 personId를 가진 유저의 자동차들을 받아올 수 있게 되며 아래와 같이
{ byId: 555, message: "getAllVehiclesByPersonId" }
라는 값을 보여준다.
api 내에서는 파일명이 그대로 URL로 사용될 수 있다. pages에서 페이지들을 만들어서 접근할 때에는 폴더(vehicles)를 먼저 생성해서 이 폴더의 내부에 index.ts를 생성하여 페이지를 만들지 않고 폴더 없이 vehicles.ts로 바로 만들게 되면 페이지가 나타나지 않았었다.(직접 해봤을 때 영상과 다른 부분이다.)
그런데 파일 확장자를 js로 바꾸었더니 페이지가 잘 렌더링되었고 다시 ts로 변경하니 페이지가 잘 렌더링되는 것을 확인했다. 코드 상으로는 오타가 없었는데 확장자만 변경하는 것으로 페이지 오류가 사라지고 정상적으로 작동하는 것이 이상했다.
- sqlite를 설치하고 프로젝트 내에 migrations라는 폴더를 생성한다음 sql파일을 생성했다. (database를 실행해보면서 SQL ERROR가 나타나서 npm install sqlite@^3.0.0 로 다시 설치를 진행하였고 오타가 있다는 것을 알게 되었다. CREATE문의 마지막에 세미콜론을 빼먹었었다. 소괄호로 적어야 하는 것을 중괄호로 쓴다거나 세미콜론을 빼먹는 실수를 하고 다른 데에 문제가 있다고 오해하는 경우가 가끔 있는데 주의해야겠다.
Person, Vehicle이라는 테이블을 만들어준다.
이 다음은 프로젝트 루트 디렉토리에 database-test.js(개발 모드로 실행할 때 db가 setup하는 과정에서 데이터를 터미널에 출력해서 확인하는 용도로 함수를 작성함)라는 파일을 만든다. 아래의 샘플코드와 비슷하게 코드를 작성하여 실행해본다.
- 데이터베이스에서 SELECT가 작동하는지 확인하는 코드
아래와 같이 작성하였는데 JSON.stringfy를 이용해서 json 데이터를 더 가독성이 높게 바꾸어 출력하였다.
JSON.parse는 string형태를 json 오브젝트 형태로 바꿔주는 것이다. JSON.stringify는 json 오브젝트를 string으로 바꿔준다.
JSON.stringfy( json Object, replacer, space ) : space를 이용하면 문자열 간격을 변경할 수 있다.
- 3번째 파라미터에 2 대신 4를 입력하면 아래와 같이 중괄호 밑에서 4칸을 들여쓰기하게 된다.
- database-test.js에서 db가 잘 작동되는 것을 확인했고 pages/api/people.ts에서 직접 사용해볼 것이다. db에 요청하는 것은 Promise를 반환하므로 function을 async function으로 변경하여 내부에서는 await 키워드로 반환받은 값을 출력시킨다.
http://localhost:3000/api/people
- 쿼리로 id를 보내서 해당하는 자동차만 보여주도록 작성하였다.
http://localhost:3000/api/vehicle/1
대괄호를 보면 우리가 배열로 수신받고 있는 것으로 이를 없애주기 위해서는 await db.all(~)를 await db.get(~)로 바꾸어준다.
- 동일한 방식으로 person/index.ts를 작성하여 id에 맞는 유저의 프로필을 가져오게 만들어주었다. id로 1을 전달하였다.
- pages/api/[id]/vehicles.ts는 소유자의 id를 보내주면 해당 id의 유저가 가지고 있는 모든 자동차의 목록을 보여줘야하므로 await db.get > await db.all로 작성해주었다.
유저 id를 1로 전달했다.
http://localhost:3000/api/person/1/vehicles
- 이미 작성되어 있는 pages/api/person/[id]/index.ts 파일이 지금은 id를 받아서 해당 유저의 데이터를 가져오는 코드로 작성되어 있는데 Endpoint란 같은 URL을 메소드에 따라 다르게 작동하도록 만들어주는 것이므로 이제 PUT 메소드로 요청하는 경우 해당 id, email, name으로 테이블에 정보를 추가시켜주도록 코드를 작성하였다.
어플리케이션이 제대로 작동하는지 크롬 개발자도구의 콘솔을 통해서 확인해보았다.
PUT 메소드로 id2에 해당하는 유저의 이름과 이메일을 넣어주었다.
놀랍게도 해당 id는 이미 다른 데이터가 존재했었는데
새로고침하면 아래와 같이 변경된 데이터를 볼 수 있다.
API Routes using SQL Database 따라하기 완료.