nodejs-quickstart-structure 1.9.2 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/README.md +7 -7
- package/bin/index.js +2 -2
- package/docs/generateCase.md +160 -164
- package/lib/generator.js +1 -1
- package/lib/modules/app-setup.js +84 -10
- package/lib/prompts.js +1 -1
- package/package.json +4 -2
- package/templates/clean-architecture/js/src/infrastructure/webserver/server.js.ejs +25 -11
- package/templates/clean-architecture/js/src/infrastructure/webserver/swagger.js +4 -21
- package/templates/clean-architecture/js/src/interfaces/controllers/{userController.js → userController.js.ejs} +23 -0
- package/templates/clean-architecture/js/src/interfaces/graphql/context.js.ejs +13 -0
- package/templates/clean-architecture/js/src/interfaces/graphql/index.js.ejs +5 -0
- package/templates/clean-architecture/js/src/interfaces/graphql/resolvers/index.js.ejs +6 -0
- package/templates/clean-architecture/js/src/interfaces/graphql/resolvers/user.resolvers.js.ejs +27 -0
- package/templates/clean-architecture/js/src/interfaces/graphql/typeDefs/index.js.ejs +6 -0
- package/templates/clean-architecture/js/src/interfaces/graphql/typeDefs/user.types.js.ejs +17 -0
- package/templates/clean-architecture/js/src/interfaces/routes/api.js +0 -67
- package/templates/clean-architecture/ts/src/config/swagger.ts.ejs +4 -21
- package/templates/clean-architecture/ts/src/index.ts.ejs +51 -20
- package/templates/clean-architecture/ts/src/interfaces/controllers/{userController.ts → userController.ts.ejs} +28 -1
- package/templates/clean-architecture/ts/src/interfaces/graphql/context.ts.ejs +17 -0
- package/templates/clean-architecture/ts/src/interfaces/graphql/index.ts.ejs +3 -0
- package/templates/clean-architecture/ts/src/interfaces/graphql/resolvers/index.ts.ejs +4 -0
- package/templates/clean-architecture/ts/src/interfaces/graphql/resolvers/user.resolvers.ts.ejs +27 -0
- package/templates/clean-architecture/ts/src/interfaces/graphql/typeDefs/index.ts.ejs +4 -0
- package/templates/clean-architecture/ts/src/interfaces/graphql/typeDefs/user.types.ts.ejs +15 -0
- package/templates/clean-architecture/ts/src/interfaces/routes/userRoutes.ts +0 -66
- package/templates/common/Dockerfile +2 -2
- package/templates/common/README.md.ejs +27 -0
- package/templates/common/database/js/mongoose.js.ejs +0 -1
- package/templates/common/database/ts/mongoose.ts.ejs +0 -1
- package/templates/common/package.json.ejs +7 -4
- package/templates/common/swagger.yml.ejs +66 -0
- package/templates/mvc/js/src/config/swagger.js +4 -21
- package/templates/mvc/js/src/controllers/userController.js.ejs +55 -0
- package/templates/mvc/js/src/graphql/context.js.ejs +7 -0
- package/templates/mvc/js/src/graphql/index.js.ejs +5 -0
- package/templates/mvc/js/src/graphql/resolvers/index.js.ejs +6 -0
- package/templates/mvc/js/src/graphql/resolvers/user.resolvers.js.ejs +25 -0
- package/templates/mvc/js/src/graphql/typeDefs/index.js.ejs +6 -0
- package/templates/mvc/js/src/graphql/typeDefs/user.types.js.ejs +17 -0
- package/templates/mvc/js/src/index.js.ejs +38 -26
- package/templates/mvc/js/src/routes/api.js +0 -66
- package/templates/mvc/ts/src/config/swagger.ts.ejs +4 -21
- package/templates/mvc/ts/src/controllers/userController.ts.ejs +56 -1
- package/templates/mvc/ts/src/graphql/context.ts.ejs +12 -0
- package/templates/mvc/ts/src/graphql/index.ts.ejs +3 -0
- package/templates/mvc/ts/src/graphql/resolvers/index.ts.ejs +4 -0
- package/templates/mvc/ts/src/graphql/resolvers/user.resolvers.ts.ejs +27 -0
- package/templates/mvc/ts/src/graphql/typeDefs/index.ts.ejs +4 -0
- package/templates/mvc/ts/src/graphql/typeDefs/user.types.ts.ejs +15 -0
- package/templates/mvc/ts/src/index.ts.ejs +54 -26
- package/templates/mvc/ts/src/routes/api.ts +0 -66
|
@@ -84,6 +84,33 @@ npm run format
|
|
|
84
84
|
The project follows **<%= architecture %>** principles.
|
|
85
85
|
<% if (communication === 'Kafka') { -%>
|
|
86
86
|
Microservices communication handled via **Kafka**.
|
|
87
|
+
<% } else if (communication === 'GraphQL') { -%>
|
|
88
|
+
API is exposed via **GraphQL**.
|
|
89
|
+
The Apollo Sandbox UI for API exploration and documentation is available natively, fully embedded for offline development:
|
|
90
|
+
- **URL**: `http://localhost:3000/graphql` (Dynamic based on PORT)
|
|
91
|
+
If you are opening `http://localhost:3000/graphql` in your browser, you can directly run the following in the Apollo Sandbox UI:
|
|
92
|
+
|
|
93
|
+
**Query to get all users:**
|
|
94
|
+
```graphql
|
|
95
|
+
query GetAllUsers {
|
|
96
|
+
getAllUsers {
|
|
97
|
+
id
|
|
98
|
+
name
|
|
99
|
+
email
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**Mutation to create a user:**
|
|
105
|
+
```graphql
|
|
106
|
+
mutation CreateUser {
|
|
107
|
+
createUser(name: "John Doe", email: "john@example.com") {
|
|
108
|
+
id
|
|
109
|
+
name
|
|
110
|
+
email
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
```
|
|
87
114
|
<% } else { -%>
|
|
88
115
|
API is exposed via **REST**.
|
|
89
116
|
A Swagger UI for API documentation is available at:
|
|
@@ -6,7 +6,6 @@ logger = require('../utils/logger');
|
|
|
6
6
|
<% } else { %>
|
|
7
7
|
logger = require('../log/logger');
|
|
8
8
|
<% } %>
|
|
9
|
-
|
|
10
9
|
const connectDB = async () => {
|
|
11
10
|
const dbHost = process.env.DB_HOST || 'localhost';
|
|
12
11
|
const mongoURI = process.env.MONGO_URI || `mongodb://${dbHost}:27017/<%= dbName %>`;
|
|
@@ -4,7 +4,6 @@ import logger from '@/utils/logger';
|
|
|
4
4
|
<% } else { %>
|
|
5
5
|
import logger from '@/infrastructure/log/logger';
|
|
6
6
|
<% } %>
|
|
7
|
-
|
|
8
7
|
const connectDB = async (): Promise<void> => {
|
|
9
8
|
const dbHost = process.env.DB_HOST || 'localhost';
|
|
10
9
|
const mongoURI = process.env.MONGO_URI || `mongodb://${dbHost}:27017/<%= dbName %>`;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"scripts": {
|
|
7
7
|
"start": "<% if (language === 'TypeScript') { %>node dist/index.js<% } else { %>node src/index.js<% } %>",
|
|
8
8
|
"dev": "<% if (language === 'TypeScript') { %>nodemon --exec ts-node -r tsconfig-paths/register src/index.ts<% } else { %>nodemon src/index.js<% } %>"<% if (language === 'TypeScript') { %>,
|
|
9
|
-
"build": "rimraf dist && tsc && tsc-alias<% if (viewEngine && viewEngine !== 'None') { %> && cpx \"src/views/**/*\" dist/views<% } %>"<% } %>,
|
|
9
|
+
"build": "rimraf dist && tsc && tsc-alias<% if (viewEngine && viewEngine !== 'None') { %> && cpx \"src/views/**/*\" dist/views<% } %><% if (communication === 'REST APIs') { %> && cpx \"src/**/*.yml\" dist/<% } %>"<% } %>,
|
|
10
10
|
"lint": "eslint .",
|
|
11
11
|
"lint:fix": "eslint . --fix",
|
|
12
12
|
"format": "prettier --write .",
|
|
@@ -48,7 +48,10 @@
|
|
|
48
48
|
"winston-daily-rotate-file": "^5.0.0",
|
|
49
49
|
"morgan": "^1.10.0"<% if (communication === 'REST APIs') { %>,
|
|
50
50
|
"swagger-ui-express": "^5.0.0",
|
|
51
|
-
"
|
|
51
|
+
"yamljs": "^0.3.0"<% } %><% if (communication === 'GraphQL') { %>,
|
|
52
|
+
"@apollo/server": "^4.10.0",
|
|
53
|
+
"graphql": "^16.8.1",
|
|
54
|
+
"@graphql-tools/merge": "^9.0.3"<% } %>
|
|
52
55
|
},
|
|
53
56
|
"devDependencies": {
|
|
54
57
|
"nodemon": "^3.0.2"<% if (language === 'TypeScript') { %>,
|
|
@@ -68,7 +71,7 @@
|
|
|
68
71
|
"@types/sequelize": "^4.28.19",
|
|
69
72
|
<%_ } -%>
|
|
70
73
|
"@types/morgan": "^1.9.9",
|
|
71
|
-
"rimraf": "^6.0.1"<% if (viewEngine && viewEngine !== 'None') { %>,
|
|
74
|
+
"rimraf": "^6.0.1"<% if ((viewEngine && viewEngine !== 'None') || communication === 'REST APIs') { %>,
|
|
72
75
|
"cpx2": "^8.0.0"<% } %><% } %>,
|
|
73
76
|
"eslint": "^9.20.1",
|
|
74
77
|
"@eslint/js": "^9.20.0",
|
|
@@ -79,7 +82,7 @@
|
|
|
79
82
|
"lint-staged": "^15.4.3"<% if (language === 'TypeScript') { %>,
|
|
80
83
|
"typescript-eslint": "^8.24.1",
|
|
81
84
|
<% if (communication === 'REST APIs') { %> "@types/swagger-ui-express": "^4.1.6",
|
|
82
|
-
"@types/
|
|
85
|
+
"@types/yamljs": "^0.2.34",<% } %>
|
|
83
86
|
"jest": "^29.7.0",
|
|
84
87
|
"ts-jest": "^29.2.5",
|
|
85
88
|
"@types/jest": "^29.5.14",
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
openapi: 3.0.0
|
|
2
|
+
info:
|
|
3
|
+
title: <%= projectName %> API
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
description: API documentation for <%= projectName %>
|
|
6
|
+
servers:
|
|
7
|
+
- url: http://localhost:3000
|
|
8
|
+
description: Local Server
|
|
9
|
+
components:
|
|
10
|
+
schemas:
|
|
11
|
+
User:
|
|
12
|
+
type: object
|
|
13
|
+
required:
|
|
14
|
+
- name
|
|
15
|
+
- email
|
|
16
|
+
properties:
|
|
17
|
+
id:
|
|
18
|
+
type: integer
|
|
19
|
+
description: The auto-generated id of the user
|
|
20
|
+
name:
|
|
21
|
+
type: string
|
|
22
|
+
description: The name of the user
|
|
23
|
+
email:
|
|
24
|
+
type: string
|
|
25
|
+
description: The email of the user
|
|
26
|
+
example:
|
|
27
|
+
id: 1
|
|
28
|
+
name: John Doe
|
|
29
|
+
email: john@example.com
|
|
30
|
+
tags:
|
|
31
|
+
- name: Users
|
|
32
|
+
description: The users managing API
|
|
33
|
+
paths:
|
|
34
|
+
/api/users:
|
|
35
|
+
get:
|
|
36
|
+
summary: Returns the list of all the users
|
|
37
|
+
tags:
|
|
38
|
+
- Users
|
|
39
|
+
responses:
|
|
40
|
+
'200':
|
|
41
|
+
description: The list of the users
|
|
42
|
+
content:
|
|
43
|
+
application/json:
|
|
44
|
+
schema:
|
|
45
|
+
type: array
|
|
46
|
+
items:
|
|
47
|
+
$ref: '#/components/schemas/User'
|
|
48
|
+
post:
|
|
49
|
+
summary: Create a new user
|
|
50
|
+
tags:
|
|
51
|
+
- Users
|
|
52
|
+
requestBody:
|
|
53
|
+
required: true
|
|
54
|
+
content:
|
|
55
|
+
application/json:
|
|
56
|
+
schema:
|
|
57
|
+
$ref: '#/components/schemas/User'
|
|
58
|
+
responses:
|
|
59
|
+
'201':
|
|
60
|
+
description: The created user.
|
|
61
|
+
content:
|
|
62
|
+
application/json:
|
|
63
|
+
schema:
|
|
64
|
+
$ref: '#/components/schemas/User'
|
|
65
|
+
'500':
|
|
66
|
+
description: Some server error
|
|
@@ -1,23 +1,6 @@
|
|
|
1
|
-
const
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const YAML = require('yamljs');
|
|
2
3
|
|
|
3
|
-
const
|
|
4
|
-
definition: {
|
|
5
|
-
openapi: '3.0.0',
|
|
6
|
-
info: {
|
|
7
|
-
title: 'NodeJS API Service',
|
|
8
|
-
version: '1.0.0',
|
|
9
|
-
description: 'API documentation for the NodeJS Service',
|
|
10
|
-
},
|
|
11
|
-
servers: [
|
|
12
|
-
{
|
|
13
|
-
url: process.env.SERVER_URL || `http://localhost:${process.env.PORT || 3000}`,
|
|
14
|
-
description: 'Server',
|
|
15
|
-
},
|
|
16
|
-
],
|
|
17
|
-
},
|
|
18
|
-
apis: ['./src/routes/*.js'], // Path to the API docs
|
|
19
|
-
};
|
|
4
|
+
const swaggerDocument = YAML.load(path.join(__dirname, 'swagger.yml'));
|
|
20
5
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
module.exports = specs;
|
|
6
|
+
module.exports = swaggerDocument;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
const User = require('../models/User');
|
|
2
|
+
<% if (communication !== 'GraphQL') { -%>
|
|
2
3
|
const HTTP_STATUS = require('../utils/httpCodes');
|
|
4
|
+
<% } -%>
|
|
3
5
|
const logger = require('../utils/logger');
|
|
4
6
|
<%_ if (caching === 'Redis') { -%>
|
|
5
7
|
const cacheService = require('../config/redisClient');
|
|
@@ -7,6 +9,58 @@ const cacheService = require('../config/redisClient');
|
|
|
7
9
|
const cacheService = require('../config/memoryCache');
|
|
8
10
|
<%_ } -%>
|
|
9
11
|
|
|
12
|
+
<% if (communication === 'GraphQL') { -%>
|
|
13
|
+
const getUsers = async () => {
|
|
14
|
+
try {
|
|
15
|
+
<%_ if (caching === 'Redis' || caching === 'Memory Cache') { -%>
|
|
16
|
+
const users = await cacheService.getOrSet('users:all', async () => {
|
|
17
|
+
<%_ if (database === 'MongoDB') { -%>
|
|
18
|
+
return await User.find();
|
|
19
|
+
<%_ } else if (database === 'None') { -%>
|
|
20
|
+
return User.mockData;
|
|
21
|
+
<%_ } else { -%>
|
|
22
|
+
return await User.findAll();
|
|
23
|
+
<%_ } -%>
|
|
24
|
+
}, 60);
|
|
25
|
+
<%_ } else { -%>
|
|
26
|
+
<%_ if (database === 'MongoDB') { -%>
|
|
27
|
+
const users = await User.find();
|
|
28
|
+
<%_ } else if (database === 'None') { -%>
|
|
29
|
+
const users = User.mockData;
|
|
30
|
+
<%_ } else { -%>
|
|
31
|
+
const users = await User.findAll();
|
|
32
|
+
<%_ } -%>
|
|
33
|
+
<%_ } -%>
|
|
34
|
+
return users;
|
|
35
|
+
} catch (error) {
|
|
36
|
+
logger.error('Error fetching users:', error);
|
|
37
|
+
throw error;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const createUser = async (data) => {
|
|
42
|
+
try {
|
|
43
|
+
const { name, email } = data;
|
|
44
|
+
<%_ if (database === 'None') { -%>
|
|
45
|
+
const newUser = { id: String(User.mockData.length + 1), name, email };
|
|
46
|
+
User.mockData.push(newUser);
|
|
47
|
+
<%_ if (caching === 'Redis' || caching === 'Memory Cache') { -%>
|
|
48
|
+
await cacheService.del('users:all');
|
|
49
|
+
<%_ } -%>
|
|
50
|
+
return newUser;
|
|
51
|
+
<%_ } else { -%>
|
|
52
|
+
const user = await User.create({ name, email });
|
|
53
|
+
<%_ if (caching === 'Redis' || caching === 'Memory Cache') { -%>
|
|
54
|
+
await cacheService.del('users:all');
|
|
55
|
+
<%_ } -%>
|
|
56
|
+
return user;
|
|
57
|
+
<%_ } -%>
|
|
58
|
+
} catch (error) {
|
|
59
|
+
logger.error('Error creating user:', error);
|
|
60
|
+
throw error;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
<% } else { -%>
|
|
10
64
|
const getUsers = async (req, res) => {
|
|
11
65
|
try {
|
|
12
66
|
<%_ if (caching === 'Redis' || caching === 'Memory Cache') { -%>
|
|
@@ -56,6 +110,7 @@ const createUser = async (req, res) => {
|
|
|
56
110
|
res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({ error: error.message });
|
|
57
111
|
}
|
|
58
112
|
};
|
|
113
|
+
<% } -%>
|
|
59
114
|
|
|
60
115
|
module.exports = { getUsers, createUser };
|
|
61
116
|
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const { GraphQLError } = require('graphql');
|
|
2
|
+
const userController = require('../../controllers/userController');
|
|
3
|
+
|
|
4
|
+
const userResolvers = {
|
|
5
|
+
Query: {
|
|
6
|
+
getAllUsers: async () => {
|
|
7
|
+
try {
|
|
8
|
+
return await userController.getUsers();
|
|
9
|
+
} catch (error) {
|
|
10
|
+
throw new GraphQLError(error.message || 'Internal server error', { extensions: { code: 'INTERNAL_SERVER_ERROR' } });
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
Mutation: {
|
|
15
|
+
createUser: async (_, { name, email }) => {
|
|
16
|
+
try {
|
|
17
|
+
return await userController.createUser({ name, email });
|
|
18
|
+
} catch (error) {
|
|
19
|
+
throw new GraphQLError(error.message || 'Internal server error', { extensions: { code: 'INTERNAL_SERVER_ERROR' } });
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
module.exports = { userResolvers };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const userTypes = `#graphql
|
|
2
|
+
type User {
|
|
3
|
+
id: ID!
|
|
4
|
+
name: String!
|
|
5
|
+
email: String!
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
type Query {
|
|
9
|
+
getAllUsers: [User]
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
type Mutation {
|
|
13
|
+
createUser(name: String!, email: String!): User
|
|
14
|
+
}
|
|
15
|
+
`;
|
|
16
|
+
|
|
17
|
+
module.exports = { userTypes };
|
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
const express = require('express');
|
|
2
2
|
const cors = require('cors');
|
|
3
3
|
require('dotenv').config();
|
|
4
|
-
<% if (communication === 'REST APIs'
|
|
5
|
-
<% if (communication === 'Kafka') {
|
|
6
|
-
<% if (communication === '
|
|
4
|
+
<%_ if (communication === 'REST APIs') { -%>const apiRoutes = require('./routes/api');<%_ } -%>
|
|
5
|
+
<%_ if (communication === 'Kafka') { -%>const { connectKafka, sendMessage } = require('./services/kafkaService');<%_ } -%>
|
|
6
|
+
<%_ if (communication === 'GraphQL') { -%>
|
|
7
|
+
const { ApolloServer } = require('@apollo/server');
|
|
8
|
+
const { expressMiddleware } = require('@apollo/server/express4');
|
|
9
|
+
const { ApolloServerPluginLandingPageLocalDefault } = require('@apollo/server/plugin/landingPage/default');
|
|
10
|
+
const { typeDefs, resolvers } = require('./graphql');
|
|
11
|
+
const { gqlContext } = require('./graphql/context');
|
|
12
|
+
<% } -%>
|
|
13
|
+
<%_ if (communication === 'REST APIs') { -%>
|
|
7
14
|
const swaggerUi = require('swagger-ui-express');
|
|
8
15
|
const swaggerSpecs = require('./config/swagger');
|
|
9
|
-
<% } -%>
|
|
16
|
+
<%_ } -%>
|
|
10
17
|
|
|
11
18
|
const app = express();
|
|
12
19
|
const PORT = process.env.PORT || 3000;
|
|
@@ -17,22 +24,18 @@ app.use(cors());
|
|
|
17
24
|
app.use(express.json());
|
|
18
25
|
app.use(morgan('combined', { stream: { write: message => logger.info(message.trim()) } }));
|
|
19
26
|
|
|
20
|
-
<% if (communication === 'REST APIs') { -%>
|
|
27
|
+
<%_ if (communication === 'REST APIs') { -%>
|
|
21
28
|
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpecs));
|
|
22
|
-
<% } -%>
|
|
23
|
-
|
|
24
|
-
<% if (viewEngine === 'EJS' || viewEngine === 'Pug') { -%>
|
|
29
|
+
<%_ } -%>
|
|
30
|
+
<%_ if (viewEngine === 'EJS' || viewEngine === 'Pug') { -%>
|
|
25
31
|
// View Engine Setup
|
|
26
32
|
const path = require('path');
|
|
27
33
|
app.set('views', path.join(__dirname, 'views'));
|
|
28
34
|
app.set('view engine', '<%= viewEngine.toLowerCase() %>');
|
|
29
|
-
app.use(express.static(path.join(__dirname, '../public')));<% }
|
|
30
|
-
|
|
31
|
-
// Routes
|
|
32
|
-
<% if (communication === 'REST APIs' || (viewEngine && viewEngine !== 'None')) { -%>
|
|
35
|
+
app.use(express.static(path.join(__dirname, '../public')));<%_ } %>
|
|
36
|
+
<%_ if (communication === 'REST APIs') { -%>
|
|
33
37
|
app.use('/api', apiRoutes);
|
|
34
|
-
<% } -%>
|
|
35
|
-
<% if (viewEngine && viewEngine !== 'None') { -%>
|
|
38
|
+
<%_ } -%><% if (viewEngine && viewEngine !== 'None') { -%>
|
|
36
39
|
app.get('/', (req, res) => {
|
|
37
40
|
res.render('index', {
|
|
38
41
|
projectName: 'NodeJS Service',
|
|
@@ -42,24 +45,33 @@ app.get('/', (req, res) => {
|
|
|
42
45
|
});
|
|
43
46
|
});
|
|
44
47
|
<% } -%>
|
|
45
|
-
|
|
46
48
|
app.get('/health', (req, res) => {
|
|
47
49
|
res.json({ status: 'UP' });
|
|
48
50
|
});
|
|
49
51
|
|
|
50
52
|
// Start Server Logic
|
|
51
53
|
const startServer = async () => {
|
|
52
|
-
|
|
54
|
+
<%_ if (communication === 'GraphQL') { -%>
|
|
55
|
+
// GraphQL Setup
|
|
56
|
+
const server = new ApolloServer({
|
|
57
|
+
typeDefs,
|
|
58
|
+
resolvers,
|
|
59
|
+
plugins: [ApolloServerPluginLandingPageLocalDefault({ embed: true })],
|
|
60
|
+
});
|
|
61
|
+
await server.start();
|
|
62
|
+
app.use('/graphql', expressMiddleware(server, { context: gqlContext }));
|
|
63
|
+
<%_ } -%>
|
|
64
|
+
app.listen(PORT, () => {
|
|
65
|
+
logger.info(`Server running on port ${PORT}`);
|
|
53
66
|
<%_ if (communication === 'Kafka') { -%>
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
logger.error('Failed to connect to Kafka:', err);
|
|
61
|
-
}
|
|
67
|
+
connectKafka().then(() => {
|
|
68
|
+
logger.info('Kafka connected');
|
|
69
|
+
sendMessage('test-topic', 'Hello Kafka from MVC JS!');
|
|
70
|
+
}).catch(err => {
|
|
71
|
+
logger.error('Failed to connect to Kafka:', err);
|
|
72
|
+
});
|
|
62
73
|
<%_ } -%>
|
|
74
|
+
});
|
|
63
75
|
};
|
|
64
76
|
|
|
65
77
|
<%_ if (database !== 'None') { -%>
|
|
@@ -78,7 +90,7 @@ const syncDatabase = async () => {
|
|
|
78
90
|
logger.info('Database synced');
|
|
79
91
|
|
|
80
92
|
// Start Server after DB is ready
|
|
81
|
-
|
|
93
|
+
await startServer();
|
|
82
94
|
break;
|
|
83
95
|
} catch (err) {
|
|
84
96
|
logger.error('Database sync failed:', err);
|
|
@@ -91,5 +103,5 @@ const syncDatabase = async () => {
|
|
|
91
103
|
|
|
92
104
|
syncDatabase();
|
|
93
105
|
<%_ } else { -%>
|
|
94
|
-
|
|
106
|
+
startServer();
|
|
95
107
|
<%_ } -%>
|
|
@@ -2,72 +2,6 @@ const express = require('express');
|
|
|
2
2
|
const router = express.Router();
|
|
3
3
|
const userController = require('../controllers/userController');
|
|
4
4
|
|
|
5
|
-
/**
|
|
6
|
-
* @swagger
|
|
7
|
-
* components:
|
|
8
|
-
* schemas:
|
|
9
|
-
* User:
|
|
10
|
-
* type: object
|
|
11
|
-
* required:
|
|
12
|
-
* - name
|
|
13
|
-
* - email
|
|
14
|
-
* properties:
|
|
15
|
-
* id:
|
|
16
|
-
* type: integer
|
|
17
|
-
* description: The auto-generated id of the user
|
|
18
|
-
* name:
|
|
19
|
-
* type: string
|
|
20
|
-
* description: The name of the user
|
|
21
|
-
* email:
|
|
22
|
-
* type: string
|
|
23
|
-
* description: The email of the user
|
|
24
|
-
* example:
|
|
25
|
-
* id: 1
|
|
26
|
-
* name: John Doe
|
|
27
|
-
* email: john@example.com
|
|
28
|
-
*/
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* @swagger
|
|
32
|
-
* tags:
|
|
33
|
-
* name: Users
|
|
34
|
-
* description: The users managing API
|
|
35
|
-
*/
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* @swagger
|
|
39
|
-
* /api/users:
|
|
40
|
-
* get:
|
|
41
|
-
* summary: Returns the list of all the users
|
|
42
|
-
* tags: [Users]
|
|
43
|
-
* responses:
|
|
44
|
-
* 200:
|
|
45
|
-
* description: The list of the users
|
|
46
|
-
* content:
|
|
47
|
-
* application/json:
|
|
48
|
-
* schema:
|
|
49
|
-
* type: array
|
|
50
|
-
* items:
|
|
51
|
-
* $ref: '#/components/schemas/User'
|
|
52
|
-
* post:
|
|
53
|
-
* summary: Create a new user
|
|
54
|
-
* tags: [Users]
|
|
55
|
-
* requestBody:
|
|
56
|
-
* required: true
|
|
57
|
-
* content:
|
|
58
|
-
* application/json:
|
|
59
|
-
* schema:
|
|
60
|
-
* $ref: '#/components/schemas/User'
|
|
61
|
-
* responses:
|
|
62
|
-
* 201:
|
|
63
|
-
* description: The created user.
|
|
64
|
-
* content:
|
|
65
|
-
* application/json:
|
|
66
|
-
* schema:
|
|
67
|
-
* $ref: '#/components/schemas/User'
|
|
68
|
-
* 500:
|
|
69
|
-
* description: Some server error
|
|
70
|
-
*/
|
|
71
5
|
router.get('/users', userController.getUsers);
|
|
72
6
|
router.post('/users', userController.createUser);
|
|
73
7
|
|
|
@@ -1,23 +1,6 @@
|
|
|
1
|
-
<% if (communication === 'REST APIs') { %>import
|
|
1
|
+
<% if (communication === 'REST APIs') { %>import path from 'path';
|
|
2
|
+
import YAML from 'yamljs';
|
|
2
3
|
|
|
3
|
-
const
|
|
4
|
-
definition: {
|
|
5
|
-
openapi: '3.0.0',
|
|
6
|
-
info: {
|
|
7
|
-
title: 'NodeJS API Service',
|
|
8
|
-
version: '1.0.0',
|
|
9
|
-
description: 'API documentation for the NodeJS Service',
|
|
10
|
-
},
|
|
11
|
-
servers: [
|
|
12
|
-
{
|
|
13
|
-
url: process.env.SERVER_URL || `http://localhost:${process.env.PORT || 3000}`,
|
|
14
|
-
description: 'Server',
|
|
15
|
-
},
|
|
16
|
-
],
|
|
17
|
-
},
|
|
18
|
-
apis: ['./src/routes/*.ts', './dist/routes/*.js'], // Path to the API docs
|
|
19
|
-
};
|
|
4
|
+
const swaggerDocument = YAML.load(path.join(__dirname, 'swagger.yml'));
|
|
20
5
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
export default specs;<% } %>
|
|
6
|
+
export default swaggerDocument;<% } %>
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
<% if (communication !== 'GraphQL') { -%>
|
|
1
2
|
import { Request, Response } from 'express';
|
|
2
|
-
import User from '@/models/User';
|
|
3
3
|
import { HTTP_STATUS } from '@/utils/httpCodes';
|
|
4
|
+
<% } -%>
|
|
5
|
+
import User from '@/models/User';
|
|
4
6
|
import logger from '@/utils/logger';
|
|
5
7
|
<%_ if (caching === 'Redis') { -%>
|
|
6
8
|
import cacheService from '@/config/redisClient';
|
|
@@ -9,6 +11,58 @@ import cacheService from '@/config/memoryCache';
|
|
|
9
11
|
<%_ } -%>
|
|
10
12
|
|
|
11
13
|
export class UserController {
|
|
14
|
+
<% if (communication === 'GraphQL') { -%>
|
|
15
|
+
async getUsers() {
|
|
16
|
+
try {
|
|
17
|
+
<%_ if (caching === 'Redis' || caching === 'Memory Cache') { -%>
|
|
18
|
+
const users = await cacheService.getOrSet('users:all', async () => {
|
|
19
|
+
<%_ if (database === 'MongoDB') { -%>
|
|
20
|
+
return await User.find();
|
|
21
|
+
<%_ } else if (database === 'None') { -%>
|
|
22
|
+
return User.mockData;
|
|
23
|
+
<%_ } else { -%>
|
|
24
|
+
return await User.findAll();
|
|
25
|
+
<%_ } -%>
|
|
26
|
+
}, 60);
|
|
27
|
+
<%_ } else { -%>
|
|
28
|
+
<%_ if (database === 'MongoDB') { -%>
|
|
29
|
+
const users = await User.find();
|
|
30
|
+
<%_ } else if (database === 'None') { -%>
|
|
31
|
+
const users = User.mockData;
|
|
32
|
+
<%_ } else { -%>
|
|
33
|
+
const users = await User.findAll();
|
|
34
|
+
<%_ } -%>
|
|
35
|
+
<%_ } -%>
|
|
36
|
+
return users;
|
|
37
|
+
} catch (error) {
|
|
38
|
+
logger.error('Error fetching users:', error);
|
|
39
|
+
throw error;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async createUser(data: { name: string, email: string }) {
|
|
44
|
+
try {
|
|
45
|
+
const { name, email } = data;
|
|
46
|
+
<%_ if (database === 'None') { -%>
|
|
47
|
+
const newUser = { id: String(User.mockData.length + 1), name, email };
|
|
48
|
+
User.mockData.push(newUser);
|
|
49
|
+
<%_ if (caching === 'Redis' || caching === 'Memory Cache') { -%>
|
|
50
|
+
await cacheService.del('users:all');
|
|
51
|
+
<%_ } -%>
|
|
52
|
+
return newUser;
|
|
53
|
+
<%_ } else { -%>
|
|
54
|
+
const user = await User.create({ name, email });
|
|
55
|
+
<%_ if (caching === 'Redis' || caching === 'Memory Cache') { -%>
|
|
56
|
+
await cacheService.del('users:all');
|
|
57
|
+
<%_ } -%>
|
|
58
|
+
return user;
|
|
59
|
+
<%_ } -%>
|
|
60
|
+
} catch (error) {
|
|
61
|
+
logger.error('Error creating user:', error);
|
|
62
|
+
throw error;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
<% } else { -%>
|
|
12
66
|
async getUsers(req: Request, res: Response) {
|
|
13
67
|
try {
|
|
14
68
|
<%_ if (caching === 'Redis' || caching === 'Memory Cache') { -%>
|
|
@@ -67,5 +121,6 @@ export class UserController {
|
|
|
67
121
|
}
|
|
68
122
|
}
|
|
69
123
|
}
|
|
124
|
+
<% } -%>
|
|
70
125
|
}
|
|
71
126
|
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Request } from 'express';
|
|
2
|
+
|
|
3
|
+
export interface MyContext {
|
|
4
|
+
token?: string;
|
|
5
|
+
// user?: User;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const gqlContext = async ({ req }: { req: Request }): Promise<MyContext> => {
|
|
9
|
+
// Setup authorization or context here
|
|
10
|
+
const token = req.headers.authorization || '';
|
|
11
|
+
return { token };
|
|
12
|
+
};
|