처음으로 백엔드를 구성해봤다. 에러들을 만나고 aws도 직접 구성해봤는데 문제들을 만나서 상당히 힘들었다.
chatGPT한테 에러좀 해결해달라고 에러를 말했는데 잘못된 방법만 계속 알려줘서 상당히 삽질하고 뺑뺑 돌았다.
에러로인해 한 고생도 작성해보도록 하겠다.
백엔드 : node.js
chat GPT 를 활용하기 위해 OpenAI 에서 APIKey를 받아서 적용해줘야 했다.
백엔드 프로젝트를 따로 구성해야 좋다고 챗 gpt가 말했는데 달랑 index.js하나만 구성할거라서
그냥 기존 프론트엔드에서 폴더구조 하나를 만들고 backend를 구성했다.
기본 골자 코드는 이렇다.
import { Configuration, OpenAIApi } from "openai";
import express from "express";
const app = express();
app.use(express.json()); // parsing application/json
app.use(express.urlencoded({ extended: true })); //parsing application/x-www
app.post("/moviebot", async function (req, res) {
const userContent = toStrings(req.body.user);
messages = [...messages, { role: "user", content: userContent }];
const answer = await callApi(messages);
// res.send(answer);
messages = [
...messages,
{
role: "assistant",
content: toStrings(answer),
},
];
res.json({ assistant: toStrings(answer) });
});
// dev서버에서 살리기
app.listen(3000);
주석으로 설명도 약간달아 놨다. 전체 코드를 가져온것이 아니고 일부 코드를 가져왔다.
챗 GPT란게 채팅을 하려면 기존에 이어져 왔던 맥락을 설멍해야된다.
아니면 새로운 아이가 대답하는것처럼 문맥이 이어지지 않는다.
그래서 message라는 전역변수를 설정하여 계속 이어 붙여주고 이어붙여준 것을 보내준다.
그리고 app.listen(3000) 을 실행해준다. 3000은 포트 번호이다.
내부에서 서버를 실행할때는 경로에서 node index.js 명령어를 실행하면된다.
실행하고 뚱 하고 있고 뭐가 실행되었다는 코드가 안나오길래 기다려야 하는지 알았는데
뭔 소리 없이 그냥 결과 값이 안나오면 (콘솔을 안찍었을경우) 실행된것이다.
통신은 POST 로 가능하게 했는데 app.get 요청으로 GET요청으로 변경이 가능하다.
람다를 사용해서 서버를 구축하도록 하였다. 람다의 경우 코드를 실행할 경우 함수 당 결제가 이루어진다.
EC2는 서버. 를 통으로 빌리는것이고 람다는 서버리스로 함수를 실행시키고 사용안할경우 함수를 다시 재운다.
그래서 나처럼 작은 프로젝트는 서버리스로 운영하는게 더 저렴할 것이다. 특히 다시 aws로 가입해서 프리티어 혜택을 받고있어서 무료이다.
서버리스로 올리기 위해서는 코드 변화가 필요하다.
import serverless from "serverless-http";
라이브러리를 활용해서 서버리스로 운영되게 코드를 수정해준다.
// prod 서버에서 사용
export const handler = serverless(app);
그리고 기존에는 app.listen을 사용했으면 위처럼 적용해줘야 서버리스를 사용할수 있다.
코드는 완료 했고 람다 홈페이지로 이동해서 REST API 를 개설해준다.
기본 골자에는 함수 이름을 설정해주고 기본 설정들만 해주면 되고 설정이 완료가 되면
내 백엔드 폴더를 압축해줘서 압축된 폴더를 올려주면 코드가 적용되서 실행된다.
매번 백엔드 코드를 수정하면 여기와서 다시 압축 폴더를 씌워주면 된다. 아니면 aws 자체에서 코드를 수정하고 deploy하면 된다.
API 게이트웨이 부분에서 헤메긴 했었는데 API리소스를 설정해주고 API 배포를 안해주어서 약간 헤메긴 했었다.
또 중요한것이 있다. 어디서든 API를 호출하면 안된다 이게 호출될때마다 돈이 들기 때문이다.
누가 다른 곳에서 내 API를 막 사용하면 그 돈은 내가 내야 한다. 그래서 cors에러를 설정해준다.
aws 자체에서 cors 를 설정해줄수 있지만 나는 안전하게(?) 코드에 설정해주었다.
라이브러리 cors를 받아준다.
import cors from "cors";
let corsOptions = {
origin: [
"https://chatbot-1gi.pages.dev",
"http://localhost:5173",
"http://localhost:4173",
"https://cef020e8.chatbot-1gi.pages.dev",
],
credentials: true,
};
app.use(cors(corsOptions));
그리고 옵션을 만들어줘서 origin에 허용가능한 주소들을 넣어주면 된다.
처음에 코드로만 수정하고 깃헙에 배포를 진행했는데 cors오류가 해소가 안되길래 많이 헤메긴했었는데
aws로 수정된 코드를 배포해줘야 적용이 되었다… 이를 모르고 계속 왜 적용이 안되는지 push만 여러번 했다..
cors에러는 해결이 되었건만 내부 서버에서 호출하면 잘 되던 결과값이 aws restapi로 호출하면 undefiend가 나왔다.
서버 상태는 200으로 통신은 잘되는 모양이었는데 왜 그런지 해결이 안되었다.
그래서 chatGPT 에게 문제를 물어보니 코드를 보니 async await 가 설정 되어 있는데 전역변수를 수정해봐라 이런
강아지 똥같은 말만 하고 있었다. 그리고 나서 계속 내가 안된다고 찡얼대니 추가 정보를 줘야지 해석할수 있겠다며
상황 설명을 부탁했다. 그래서 호출할 때 함수와 결과 그리고 에러에 대한 문구 까지 다 주었다.
그러더니 API 게이트웨이와 람다 함수가 연결이 안된것 같다.라고 추측해서 관련된 정보도 계속 검색을 해보았다.
정확히 설정한것을 다시 확인해보고 계속 잘 확인해봐라. 다시한번 확인해봐라 라고 말하니 해결을 할 수가 없었다.
그래서 콘솔로 확인해보자니 서버리스라서 콘솔이 어디찍히는지 물어보고 aws자체 cloud watch부분에서 해당 에러를
찾을수 있었다.
에러 정보는 401에러로 api key를 다시 발급 받아서 해결할수 있었다.
간단한 에러였는데 4시간 정도 삽질하면서 어려워 했었다..
근데 같은조건으로 내부 서버로 작동할때는 분명 잘되었으며 같은 API key였는데 왜 안됬을지.. 지금 생각해봐도 의아하긴 하다..
아무튼 문제를 해결할수 있었다.
aws의 cloudWatch 에서 에러를 확인해서 문제를 해결할수 있다 라는 정보를 알수 있었다.
근데 console.log 찍은 값도 볼수 있다고 chatGPT가 말해줬는데 콘솔값은 어디서 보는지 잘 모르겠다.
다 확인해봤는데 콘솔값이 안보인다..
아무튼 배포된 사이트에서도 결국 통신이 되도록 해결할수 있었다.
배포된 서버에서도 잘된다 !
배포된 홈페이지 : https://chatbot-1gi.pages.dev/catbot
깃허브 주소 : https://github.com/leemj0948/chatbot/tree/main/backend