Yubin, Hsu
TSID / NTAP
Environment
Editor
mkdir myMernProject
cd myMernProject
git init
mkdir backend
cd backend
npm init
npm i fastify fastify-cors pino-pretty mongoose dotenv
npm i -D typescript @types/node @types/mongoose
npx tsc --init
edit backend/tsconfig.json
"include": ["src/**/*.ts"],
"exclude": ["node_modules", ".vscode"],
"compilerOptions": {
"outDir": "./out",
"rootDir": "./src",
}
create backend/.env
MONGO_HOST=localhost
MONGO_PORT=27017
MONGO_DATABASE=mern_demo
FASTIFY_PORT=8888
FASTIFY_ENABLE_LOGGING=true
ENV=dev
create backend/src/plugins/mongodb.ts
import mongoose from 'mongoose'
import * as dotEnv from 'dotenv'
dotEnv.config()
const host = process.env.MONGO_HOST || 'localhost'
const port = process.env.MONGO_PORT || 27017
const database = process.env.MONGO_DATABASE || 'fastify'
const establishConnection = () => {
if (!process.env.JEST_WORKER_ID && mongoose.connection.readyState === 0) {
mongoose.connect(
`mongodb://${host}:${port}/${database}`,
{ useNewUrlParser: true, useUnifiedTopology: true, useFindAndModify: false },
(err) => {
if (!err) console.log('MongoDB connection successful.')
else console.log('Error in DB connection : ' + JSON.stringify(err, undefined, 2))
}
)
} else {
console.log('MongoDB has connected.')
}
}
export { establishConnection }
create backend/src/server.ts
import fastify, { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify'
import { Server, IncomingMessage, ServerResponse } from 'http'
import { establishConnection } from './plugins/mongodb'
const server: FastifyInstance<Server, IncomingMessage, ServerResponse> = fastify({
logger: { prettyPrint: true }
})
const startFastify: (port: number) => FastifyInstance<Server, IncomingMessage, ServerResponse> = (port) => {
server.register(require('fastify-cors'), {})
server.listen(port, (err, _) => {
if (err) {
console.error(err)
}
establishConnection()
})
server.get('/ping', async (request: FastifyRequest, reply: FastifyReply) => {
return reply.status(200).send({ msg: 'pong' })
})
return server
}
export { startFastify }
create backend/src/index.ts
import { startFastify } from './server'
// Start your server
const server = startFastify(8888)
export { server }
docker run -d -p 27017:27017 mongo
tsc
node out/index.js
visit the endpoint
Add Mongo Schema
create backend/src/models/cat.ts
import { model, Schema } from 'mongoose'
const catSchema: Schema = new Schema(
{
name: {
type: String,
required: true
}
},
{
timestamps: true
}
)
export default model("Cat", catSchema)
add API endpoint
import Cat from './models/cat'
server.get('/cats', async (request: FastifyRequest, reply: FastifyReply) => {
const cats = await Cat.find({}).exec()
return reply.status(200).send({ cats })
})
visit the endpoint
Create a endpoint for adding data
server.post('/cats', async (request: FastifyRequest, reply: FastifyReply) => {
const postBody = request.body
const cat = await Cat.create(postBody)
return reply.status(200).send({ cat })
})
rebuild and rerun
Thunder Client
POST http://localhost:8888/cats
with json body
{
"name": "fatOrange"
}
Get the response
Finish API
Define custom npm scripts
"scripts": {
"build": "tsc",
"start": "node out/index.js"
},
Use custom npm script
Create a Frontend (React) Project
Use create-react-app module
https://github.com/facebook/create-react-app
cd ..
npx create-react-app frontend --template typescript
Run the frontend project
cd frontend
npm run start
Final project repo
Product X