May 06, 2023
nuxt3 서버에서 api를 만들려면 server/api
디렉토리 안에 파일을 만들면 된다.
nuxt는 ~/server/api
directory를 자동으로 스캔해 api를 등록한다.
예를 들어, server/api/ai.ts
-> /api/ai
endpoint가 생긴다.
앱 내에서 $fetch("/api/ai")
를 통해 API를 호출할 수 있다.
// ~/server/api/ai.ts
export default defineEventHandler(() => {
return { message: 'success' }
})
예제로 잘 작동하는 것을 확인한 후에 구현하고자 하는 로직을 추가했다. 간단하게 message를 받아 openai api에 보낸 응답값을 return하는 api이다.
// ~/server/api/ai.ts
import { Configuration, OpenAIApi } from 'openai'
export default defineEventHandler(async event => {
const body: { message: string } = await readBody(event)
const { OPENAI_API_KEY } = useRuntimeConfig()
const configuration = new Configuration({
apiKey: OPENAI_API_KEY,
})
const openai = new OpenAIApi(configuration)
const completion = await openai.createCompletion({
model: 'text-davinci-003',
prompt: body.message,
})
return completion.data.choices[0].text
})
파일은 보는바와 같이 defineEventHandler로 감싸서 export하면 된다.
여기서 문서를 참고해야 했던 부분은
먼저 env는 process.env를 통해 접근할 수 없고, nuxt runtime config를 이용해야 했다.
nuxt.config.ts
에서 runtimeConfig에 등록하면 앱에서 useRuntimeConfig
를 통해 접근할 수 있다.
사용하기에 번거로워진 거 같은데, 공식문서에서 이는 .env 내용이 변경되었을 때 변화를 감지해 HMR을 지원하기 위함이라고 한다.
// nuxt.config.ts
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
runtimeConfig: {
OPENAI_API_KEY: process.env.OPENAI_API_KEY,
},
})
전달받는 event가 H3Event 타입이어서 생소했는데, body를 읽는 방식은 공식 문서에 나와 있듯이 readBody
api를 활용하면 됐다.
추가적으로, 파일명으로 allow method를 지정할 수 있다.
ai.ts
-> ai.post.ts
로 변경하면 post method만 허용한다.