Compare commits
28 Commits
350afad500
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
c999b4a8f6
|
|||
|
7a2c3dec97
|
|||
|
9ef8db077f
|
|||
|
da0235c0b3
|
|||
| 0378f270fc | |||
|
03458fe00c
|
|||
|
c41002a96b
|
|||
| 00eedce6ea | |||
|
|
84656ec61a | ||
| dd445a22c0 | |||
| 923e08949b | |||
| 70f0ef93f8 | |||
| 1dfad5d122 | |||
| 744c6585bb | |||
| a00c5b0650 | |||
| 5120752ecb | |||
| 20fa35a575 | |||
| 67c94211e7 | |||
| a6546b7676 | |||
| c7f3aa02b5 | |||
| 9af0a6728e | |||
| 75f0d3a092 | |||
| 28e7cce904 | |||
| 4ce24d1e30 | |||
| c095086d4f | |||
| c47221cb13 | |||
| e0f16081b0 | |||
| ce813262c3 |
10
.drone.yml
10
.drone.yml
@@ -1,10 +1,14 @@
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: ci
|
||||
|
||||
steps:
|
||||
- name: submodules
|
||||
image: d.ctdn.net/alpine/git
|
||||
commands:
|
||||
- git submodule update --init --recursive
|
||||
- name: build
|
||||
image: d.ctdn.net/node
|
||||
commands:
|
||||
- npm config set registry https://r.ctdn.net
|
||||
- npm install
|
||||
- npm run build
|
||||
- yarn config set registry https://r.ctdn.net
|
||||
- yarn && yarn build
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -118,5 +118,7 @@ dist
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
|
||||
.DS_Store
|
||||
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,3 +1,6 @@
|
||||
[submodule "packages/ts-common"]
|
||||
path = packages/ts-common
|
||||
url = https://git.cubetiqs.com/CUBETIQ/ts-common.git
|
||||
[submodule "packages/cubetiq-express-server"]
|
||||
path = packages/cubetiq-express-server
|
||||
url = https://git.cubetiqs.com/CUBETIQ/cubetiq-express-server.git
|
||||
|
||||
@@ -13,10 +13,8 @@ RUN apk update && \
|
||||
WORKDIR /app
|
||||
COPY . /app
|
||||
|
||||
RUN npm config set registry https://r.ctdn.net
|
||||
RUN npm config get registry
|
||||
RUN npm install
|
||||
RUN npm run build
|
||||
RUN yarn config set registry https://r.ctdn.net
|
||||
RUN yarn && yarn build
|
||||
|
||||
EXPOSE 3000
|
||||
CMD [ "npm" , "serve"]
|
||||
CMD [ "yarn" , "serve"]
|
||||
129
README.md
129
README.md
@@ -1,4 +1,5 @@
|
||||
# Express Nodejs App
|
||||
|
||||
- Nodejs
|
||||
- Express
|
||||
- TypeScript
|
||||
@@ -7,6 +8,132 @@
|
||||
- Docker
|
||||
- DroneCI
|
||||
- Lerna Support
|
||||
- Support decorators
|
||||
|
||||
# Quickstart
|
||||
|
||||
- Clone repository
|
||||
|
||||
```shell
|
||||
git clone https://git.cubetiqs.com/CUBETIQ/express-nodejs-app.git --recurse-submodules --remote-submodules
|
||||
```
|
||||
|
||||
- Update an existed repository
|
||||
|
||||
```shell
|
||||
git submodule update --init --remote
|
||||
```
|
||||
|
||||
- Add Packages
|
||||
|
||||
```shell
|
||||
mkdir packages && git submodule add https://git.cubetiqs.com/CUBETIQ/ts-common.git packages/ts-common && git submodule add https://git.cubetiqs.com/CUBETIQ/cubetiq-express-server.git packages/cubetiq-express-server
|
||||
```
|
||||
|
||||
- Install and Build Packages
|
||||
|
||||
```shell
|
||||
yarn && npx lerna run build
|
||||
```
|
||||
|
||||
- Start
|
||||
|
||||
```shell
|
||||
yarn start
|
||||
```
|
||||
|
||||
- Navigate
|
||||
|
||||
```shell
|
||||
curl http://localhost:3000/info
|
||||
```
|
||||
|
||||
- Response
|
||||
|
||||
```json
|
||||
{
|
||||
"startedAt": "2021-09-13T13:21:04.184Z",
|
||||
"message": "Instance id: presenter#143470",
|
||||
"status": "OK"
|
||||
}
|
||||
```
|
||||
|
||||
# Build application
|
||||
|
||||
```shell
|
||||
yarn build
|
||||
```
|
||||
|
||||
# Quick Register Controller
|
||||
|
||||
- Add new controller `src/controller/home.controller.ts`
|
||||
|
||||
```typescript
|
||||
import { Request, Response } from "express"
|
||||
import { Controller, Get, Post, Delete } from "../decorators"
|
||||
|
||||
const data: any[] = []
|
||||
|
||||
@Controller("/home")
|
||||
export default class HomeController {
|
||||
constructor() {}
|
||||
|
||||
@Get()
|
||||
public get(req: Request, res: Response) {
|
||||
res.json(data)
|
||||
}
|
||||
|
||||
@Post()
|
||||
public create(req: Request, res: Response) {
|
||||
const body = req.body
|
||||
if (body == null) {
|
||||
return res.status(400).json({
|
||||
status: 400,
|
||||
message: "Data is required",
|
||||
})
|
||||
}
|
||||
|
||||
data.push(body)
|
||||
res.json({
|
||||
message: "Data created successfully",
|
||||
body: body,
|
||||
})
|
||||
}
|
||||
|
||||
@Delete("/:id")
|
||||
public get(req: Request, res: Response) {
|
||||
const id = req.params.id
|
||||
res.json({
|
||||
id: id,
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- Register controller into index.ts `(src/controllers/index.ts)`
|
||||
|
||||
```ts
|
||||
import IndexController from "./index.controller"
|
||||
import PersonController from "./person.controller"
|
||||
import HomeController from "./home.controller"
|
||||
|
||||
export const controllers = [IndexController, PersonController, HomeController]
|
||||
```
|
||||
|
||||
- Output registered routes
|
||||
|
||||
```ts
|
||||
┌─────────┬──────────────────────┬─────────────────────────────────┐
|
||||
│ (index) │ api │ handler │
|
||||
├─────────┼──────────────────────┼─────────────────────────────────┤
|
||||
│ 0 │ 'GET /hello' │ 'IndexController.index' │
|
||||
│ 1 │ 'GET /hello/:name' │ 'IndexController.hello' │
|
||||
│ 2 │ 'GET /person' │ 'PersonController.getPersons' │
|
||||
│ 3 │ 'POST /person' │ 'PersonController.createPerson' │
|
||||
│ 4 │ 'DELETE /person/:id' │ 'PersonController.deletePerson' │
|
||||
└─────────┴──────────────────────┴─────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Contributors
|
||||
- Sambo Chea <sombochea@cubetiqs.com>
|
||||
|
||||
- Sambo Chea <sombochea@cubetiqs.com> [4099C19544D3FF79]
|
||||
|
||||
21
package.json
21
package.json
@@ -1,15 +1,16 @@
|
||||
{
|
||||
"name": "@cubetiq/express-nodejs-app",
|
||||
"version": "1.0.0",
|
||||
"description": "Express, Nodejs application for service",
|
||||
"description": "Express, Nodejs application for micro-service",
|
||||
"main": "dist/app.js",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "ts-node-dev --respawn --transpile-only src/app.ts",
|
||||
"build": "rm -rf dist && tsc",
|
||||
"serve": "yarn run build && node dist/app.js",
|
||||
"build": "lerna run build && rm -rf dist && tsc",
|
||||
"serve": "yarn build && node dist/app.js",
|
||||
"bootstrap": "lerna bootstrap",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"prepare": "husky install"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -17,12 +18,14 @@
|
||||
},
|
||||
"keywords": [
|
||||
"Express",
|
||||
"Nodejs"
|
||||
"Nodejs",
|
||||
"Typescript"
|
||||
],
|
||||
"author": "Sambo Chea <sombochea@cubetiqs.com>",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"@types/express": "^4.17.13",
|
||||
"@types/node": "^16.9.1",
|
||||
"@typescript-eslint/eslint-plugin": "^4.30.0",
|
||||
"@typescript-eslint/parser": "^4.30.0",
|
||||
"dotenv": "^10.0.0",
|
||||
@@ -35,12 +38,12 @@
|
||||
"lint-staged": "^11.1.2",
|
||||
"prettier": "2.3.2",
|
||||
"ts-node-dev": "^1.1.8",
|
||||
"typescript": "^4.4.2",
|
||||
"@types/node": "^16.9.1"
|
||||
"typescript": "^4.4.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"express": "^4.17.1",
|
||||
"@cubetiq/ts-common": "1.0.0"
|
||||
"@cubetiq/ts-common": "1.0.0",
|
||||
"@cubetiq/express-server": "1.0.0",
|
||||
"express": "^4.17.1"
|
||||
},
|
||||
"lint-staged": {
|
||||
"**/*": "prettier --write --ignore-unknown"
|
||||
|
||||
1
packages/cubetiq-express-server
Submodule
1
packages/cubetiq-express-server
Submodule
Submodule packages/cubetiq-express-server added at b03dd8ad39
Submodule packages/ts-common updated: c42964407e...e26ee50faf
27
src/app.ts
27
src/app.ts
@@ -1,5 +1,28 @@
|
||||
// app config
|
||||
import "./dotenv"
|
||||
|
||||
// core app
|
||||
import "./server"
|
||||
import { createServer } from "http"
|
||||
import { SERVER_PORT } from "./app.config"
|
||||
import { info } from "@cubetiq/ts-common/dist/log"
|
||||
import application from "./server"
|
||||
|
||||
// get current host id
|
||||
const hostId = `${require("os").hostname()}#${process.pid}`
|
||||
const startedAt = new Date()
|
||||
|
||||
const app = application.instance
|
||||
const httpServer = createServer(app)
|
||||
|
||||
info(
|
||||
`Application server running on: ${hostId} at port: ${SERVER_PORT} and started at: ${startedAt}`
|
||||
)
|
||||
httpServer.listen(SERVER_PORT)
|
||||
|
||||
app.get("/info", (req, res) => {
|
||||
res.type("json")
|
||||
res.send({
|
||||
startedAt,
|
||||
message: `Instance id: ${hostId}`,
|
||||
status: "OK",
|
||||
})
|
||||
})
|
||||
|
||||
17
src/controller/index.controller.ts
Normal file
17
src/controller/index.controller.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { Request, Response } from "express"
|
||||
import { Controller, Get } from "@cubetiq/express-server/dist/decorators"
|
||||
|
||||
@Controller("/hello")
|
||||
export default class IndexController {
|
||||
constructor() {}
|
||||
|
||||
@Get("")
|
||||
public index(req: Request, res: Response) {
|
||||
res.send(`Hello Index`)
|
||||
}
|
||||
|
||||
@Get("/:name")
|
||||
public hello(req: Request, res: Response) {
|
||||
res.send(`Hello ${req.params.name}`)
|
||||
}
|
||||
}
|
||||
4
src/controller/index.ts
Normal file
4
src/controller/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import IndexController from "./index.controller"
|
||||
import PersonController from "./person.controller"
|
||||
|
||||
export const controllers = [IndexController, PersonController]
|
||||
67
src/controller/person.controller.ts
Normal file
67
src/controller/person.controller.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
import { Request, Response } from "express"
|
||||
import {
|
||||
Controller,
|
||||
Delete,
|
||||
Get,
|
||||
Post,
|
||||
} from "@cubetiq/express-server/dist/decorators"
|
||||
|
||||
const persons: Array<any> = [
|
||||
{
|
||||
id: 1,
|
||||
name: "Sambo",
|
||||
},
|
||||
]
|
||||
|
||||
@Controller("/person")
|
||||
export default class PersonController {
|
||||
@Get()
|
||||
public getPersons(req: Request, res: Response) {
|
||||
res.json(persons)
|
||||
}
|
||||
|
||||
@Post()
|
||||
public createPerson(req: Request, res: Response) {
|
||||
const person = req.body
|
||||
|
||||
if (person == null) {
|
||||
return res.status(400).json({
|
||||
status: 400,
|
||||
message: "Person is required",
|
||||
})
|
||||
}
|
||||
|
||||
persons.push(person)
|
||||
res.json({
|
||||
message: "Person created successfully",
|
||||
body: person,
|
||||
})
|
||||
}
|
||||
|
||||
@Delete("/:id")
|
||||
public deletePerson(req: Request, res: Response) {
|
||||
const id = req.params.id
|
||||
|
||||
if (id == null) {
|
||||
return res.status(400).json({
|
||||
status: 400,
|
||||
message: "Id is required",
|
||||
})
|
||||
}
|
||||
|
||||
const person = persons.find((person) => person.id === Number(id))
|
||||
|
||||
if (person == null) {
|
||||
return res.status(404).json({
|
||||
status: 404,
|
||||
message: "Person not found",
|
||||
})
|
||||
}
|
||||
|
||||
persons.splice(persons.indexOf(person), 1)
|
||||
res.json({
|
||||
message: "Person deleted successfully",
|
||||
body: person,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,25 +1,9 @@
|
||||
import { createServer } from "http"
|
||||
import Express from "express"
|
||||
import { SERVER_PORT } from "./app.config"
|
||||
import { info } from "@cubetiq/ts-common/dist/log"
|
||||
import Application from "@cubetiq/express-server/dist"
|
||||
import { controllers as AllControllers } from "./controller"
|
||||
class Server extends Application {
|
||||
get controllers(): any[] {
|
||||
return AllControllers
|
||||
}
|
||||
}
|
||||
|
||||
// get current host id
|
||||
const hostId = `${require("os").hostname()}#${process.pid}`
|
||||
const startedAt = new Date()
|
||||
|
||||
const app = Express()
|
||||
const httpServer = createServer(app)
|
||||
|
||||
info(
|
||||
`Application server running on: ${hostId} at port: ${SERVER_PORT} and started at: ${startedAt}`
|
||||
)
|
||||
httpServer.listen(SERVER_PORT)
|
||||
|
||||
app.get("/", (req, res) => {
|
||||
res.type("json")
|
||||
res.send({
|
||||
startedAt,
|
||||
message: `Instance id: ${hostId}`,
|
||||
status: "OK",
|
||||
})
|
||||
})
|
||||
export default new Server()
|
||||
|
||||
1
src/utils/utils.ts
Normal file
1
src/utils/utils.ts
Normal file
@@ -0,0 +1 @@
|
||||
// nothing here for now
|
||||
@@ -3,13 +3,15 @@
|
||||
"target": "es5",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"sourceMap": true,
|
||||
"sourceMap": false,
|
||||
"outDir": "dist",
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"lib": ["ES2015"],
|
||||
"skipLibCheck": true
|
||||
"skipLibCheck": true,
|
||||
"experimentalDecorators": true
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
Reference in New Issue
Block a user