fastify 기초 학습하기
지난 포스팅에서 fastify를 설치하여 처음 실행시켜보았다면 이번에는 fastify의 기초적인 기능 몇 가지를 시도해 볼 것이다.
개발환경 구축하기
먼저 fastify의 설치부터 시작해보겠다. npm을 이용하여
$ npm i fastify --save
명령어로 설치한다.
server를 시작시켜주는 server.js파일을 생성하고 다음 내용을 작성한다.
//server.jsconst fastify = require('fastify')()
fastify.get('/', async (request, reply) => {
return { hello: 'world' }
})
fastify.listen(3000, function (err) {
if (err) throw err
fastify.log.info(`server listening on ${fastify.server.address().port}`)
})
작성이 완료되었으면
$ node server.js
명령어를 사용해 서버를 실행시켜보고 localhost:3000으로 접속해 잘 동작 하는지 확인해 볼 수 있다.
다음은 node의 명령어들을 es6 code로 작성하기 위한 트렌스파일링 설정을 해 줄 것이다.
$ npm i — save-dev babel-cli babel-preset-es2015 babel-preset-stage-2 nodemon
npm 모듈을 이용해 바벨을 설치해주고 package.json파일에는 npm명령어를 이용해 nodemon을 실행할 수 있도록 설정해준다.
“scripts”: {
"start": "nodemon server.js --exec babel-node"
}
그 다음은 .babelrc 설정파일 역시 만들어준다.
// .babelrc
{
"presets": ["es2015", "stage-2"],
"plugins": []
}
작성이 완료되었으면
$ npm run start
로 서버를 실행시켜본다.
router 분리하기
이번에는 fastify의 register API를 이용하여 router부분을 분리해볼 것이다.
먼저 our-first-route.js라는 파일을 만들어주고 해당 파일에는 server.js파일에 작성되어 있던 라우팅 부분을 옮겨주고 외부에서 사용할 수 있도록 export시켜준다.
// our-first-route.js
async function routes (fastify, options) {
fastify.get('/', async (request, reply) => {
return { hello: 'world' }
})
}
module.exports = routes
다음에는 server.js에서 routes function을 import하여 register API로 등록시켜준다.
// server.jsimport router from './our-first-routes';
fastify.register(router);
서버가 실행되는 상태에서 root url로 접속하면 정상적으로 작동하는 것을 확인할 수 있다.
DB(MongoDB) 연결하기
먼저 MongoDB와 fastify server를 연결하기 위해서는 db가 실행중이여야 한다.
해당 페이지를 통해서 mongodb를 설치하고 ‘mongo’명령어를 통해 잘 접속이 되는지까지 확인해보아야 한다. 접속 이후에는 테스트용 db와 collection, data를 생성해주어야 한다.
test db의 test collection에 {id: 1, name: “name1”}이라는 데이터를 만들어주었다.
> use test
> db.test.insert({"name":"test"})
mongodb가 잘 실행되고 있는지를 확인한 이후에는 our-db-connector.js파일을 생성하여 다음 내용을 작성해준다.
// our-db-connector.js
import fp from 'fastify-plugin'
import mongodb from 'mongodb'
const MongoClient = mongodb.MongoClient
async function db (fastify, options) {
const url = options.url
delete options.url
const db = await MongoClient.connect(url, options)
fastify.decorate('mongo', db)
}
export default fp(db)
fastify와 options정보를 받아 MongoClient.connect()로 연결해준다. 이후에는 server.js에서 import하여 router와 마찬가지로 register해준다.
// server.jsconst fastify = require('fastify')()
import dbConnector from './our-db-connector';
import router from './our-first-routes';
fastify.register(dbConnector, {
url: 'mongodb://localhost:27017/test',
useNewUrlParser: true
})
fastify.register(router);
fastify.listen(3000, function (err) {
if (err) throw err
fastify.log.info(`server listening on ${fastify.server.address().port}`)
})
다음은 라우터에서 특정 uri로 요청을 보냈을 때 DB의 데이터를 조회해오는 로직을 작성해준다.
async function routes (fastify, options) {
const collection = fastify.mongo.db('test').collection('test')
...
fastify.get('/search/:id', async (request, reply) => {
try {
return await collection.findOne({ id: parseInt(request.params.id) })
} catch (err) {
reg.log.error(err)
return new Error('Something went wrong')
}
})
}
export default routes
‘test’ db의 ‘test’ collection에 접근하여 request parameter로 넘어온 id값을 조회해주었다. 이제 ‘localhost:3000/search/1’로 접근해면 해당 data를 잘 응답해주는 것을 확인할 수 있다.
request, response data type 지정
fastify에서는 JSON타입으로 request와 response의 데이터 타입과 형식을 설정해줄 수 있다.
const opts = {
schema: {
body: {
type: 'object',
properties: {
someKey: { type: 'string' },
someOtherKey: { type: 'number' }
}
}, response: {
200: {
type: 'object',
properties: {
hello: { type: 'string' }
}
}
}
}
}
fastify.get('/', opts, async (request, reply) => {
return { hello: 'world' }
})
다음과 같이 설정하여 request body는 json object로 key값은 string과 number로 지정할 수 있고(GET method로 요청을 라우팅하고 있기 때문에 root url로 요청하면 bad request error를 반환하는 것이 정상이다. 핵심은 body형태를 사전에 지정해줄 수 있다는 것), response는 json object이며 string type의 hello를 반환하도록 지정해줄 수 있다.