├── .gitignore
├── README.md
├── index.ts
├── package.json
└── tsconfig.json
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | lib/
3 | package-lock.json
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Node.js with MongoDB Example
2 |
3 |
4 |
5 | ### Requirements
6 |
7 | - Node.js v10+
8 | - MongoDB running on local instance
9 |
10 | #### Environment Variables
11 |
12 | - PORT: 3000
13 | - MONGO_URL: localhost:27017
14 |
15 | ### Running
16 |
17 | - Install dependencies - `npm i`
18 | - Build typescript - `npm run build`
19 | - Run project - `npm start`
20 | - Go to swagger page - `localhost:3000/`
21 |
22 | ### Development with Watch Compiler
23 |
24 | - Run once - `npm run dev`
25 | - Run and watch files - `npm run dev:watch`
26 |
--------------------------------------------------------------------------------
/index.ts:
--------------------------------------------------------------------------------
1 | // import * as Hapi from 'hapi';
2 | import * as Joi from '@hapi/joi';
3 | import * as Inert from '@hapi/inert';
4 | import * as Vision from '@hapi/vision';
5 | import * as Hapi from '@hapi/hapi';
6 |
7 | import { MongoClient, ObjectId } from 'mongodb';
8 |
9 | const HapiSwagger = require('hapi-swagger');
10 |
11 | const port = process.env.PORT || 3000;
12 | const server = new Hapi.Server({
13 | port,
14 | routes: {
15 | cors: {
16 | origin: ['*'],
17 | },
18 | },
19 | });
20 |
21 | (async () => {
22 | const host = process.env.MONGO_URL || 'localhost';
23 | const connectionString = `mongodb://${host}/heroes`;
24 | const connection = await MongoClient.connect(connectionString, {
25 | useNewUrlParser: true,
26 | });
27 | console.log('mongo db is running');
28 |
29 | const db = connection.db('heroes').collection('hero');
30 |
31 | await server.register([
32 | Inert,
33 | Vision,
34 | {
35 | plugin: HapiSwagger,
36 | options: {
37 | info: {
38 | title: 'Node.js with MongoDB Example - Erick Wendel',
39 | version: 'v1.0',
40 | },
41 | },
42 | },
43 | ]);
44 |
45 | server.route([
46 | {
47 | method: 'GET',
48 | path: '/',
49 | config: {
50 | handler: (r, reply) => reply.redirect('/documentation'),
51 | },
52 | },
53 | {
54 | method: 'GET',
55 | path: '/heroes',
56 | config: {
57 | handler: () => {
58 | return db.find().toArray();
59 | },
60 | description: 'List All heroes',
61 | notes: 'heroes from database',
62 | tags: ['api'],
63 | },
64 | },
65 | {
66 | method: 'POST',
67 | path: '/heroes',
68 | config: {
69 | handler: req => {
70 | const { payload } = req;
71 | return db.insert(payload);
72 | },
73 | description: 'Create a hero',
74 | notes: 'create a hero',
75 | tags: ['api'],
76 | validate: {
77 | payload: {
78 | name: Joi.string().required(),
79 | power: Joi.string().required(),
80 | },
81 | },
82 | },
83 | },
84 | {
85 | method: 'PUT',
86 | path: '/heroes/{id}',
87 | config: {
88 | handler: req => {
89 | const { payload } = req;
90 | const {
91 | params: { id },
92 | } = req;
93 | return db.updateOne({ _id: new ObjectId(id) }, { $set: payload });
94 | },
95 | description: 'Update a hero',
96 | notes: 'Update a hero',
97 | tags: ['api'],
98 | validate: {
99 | params: {
100 | id: Joi.string().required(),
101 | },
102 | payload: {
103 | name: Joi.string(),
104 | power: Joi.string(),
105 | },
106 | },
107 | },
108 | },
109 | {
110 | method: 'DELETE',
111 | path: '/heroes/{id}',
112 | config: {
113 | handler: req => {
114 | return db.deleteOne({ _id: new ObjectId(req.params.id) });
115 | },
116 | description: 'Delete a hero',
117 | notes: 'Delete a hero',
118 | tags: ['api'],
119 | validate: {
120 | params: {
121 | id: Joi.string().required(),
122 | },
123 | },
124 | },
125 | },
126 | ]);
127 |
128 | await server.start();
129 | console.log('server running at', port);
130 | })();
131 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nodejs-with-mongodb-api-example",
3 | "version": "1.0.0",
4 | "description": "
",
5 | "main": "index.js",
6 | "scripts": {
7 | "build": "npx typescript",
8 | "build:watch": "npx typescript -w",
9 | "dev": "npx concurrently \"npm run build\" \"npm run dev:run\"",
10 | "dev:watch": "npx concurrently \"npm run build:watch\" \"npm run dev:run\"",
11 | "dev:run": "npx nodemon lib/index.js",
12 | "start": "node lib/index.js",
13 | "test": "echo \"Error: no test specified\" && exit 1"
14 | },
15 | "repository": {
16 | "type": "git",
17 | "url": "git+https://github.com/ErickWendel/nodejs-with-mongodb-api-example.git"
18 | },
19 | "keywords": [],
20 | "author": "",
21 | "license": "ISC",
22 | "bugs": {
23 | "url": "https://github.com/ErickWendel/nodejs-with-mongodb-api-example/issues"
24 | },
25 | "homepage": "https://github.com/ErickWendel/nodejs-with-mongodb-api-example#readme",
26 | "devDependencies": {
27 | "concurrently": "^4.1.1",
28 | "nodemon": "1.19.1",
29 | "typescript": "^3.7.3"
30 | },
31 | "dependencies": {
32 | "@hapi/hapi": "18.3.1",
33 | "@hapi/inert": "5.2.1",
34 | "@hapi/joi": "15.1.0",
35 | "@hapi/vision": "5.5.2",
36 | "@types/mongodb": "3.1.32",
37 | "hapi-swagger": "10.0.2",
38 | "mongodb": "3.3.0-beta2"
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | /* Basic Options */
4 | "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
5 | "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
6 | "lib": [
7 | "es2019"
8 | ], /* Specify library files to be included in the compilation. */
9 | // "allowJs": true, /* Allow javascript files to be compiled. */
10 | // "checkJs": true, /* Report errors in .js files. */
11 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
12 | // "declaration": true, /* Generates corresponding '.d.ts' file. */
13 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
14 | // "sourceMap": true, /* Generates corresponding '.map' file. */
15 | // "outFile": "./", /* Concatenate and emit output to single file. */
16 | "outDir": "./lib", /* Redirect output structure to the directory. */
17 | // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
18 | // "composite": true, /* Enable project compilation */
19 | // "incremental": true, /* Enable incremental compilation */
20 | // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
21 | // "removeComments": true, /* Do not emit comments to output. */
22 | // "noEmit": true, /* Do not emit outputs. */
23 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */
24 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
25 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
26 | /* Strict Type-Checking Options */
27 | "strict": false, /* Enable all strict type-checking options. */
28 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
29 | // "strictNullChecks": true, /* Enable strict null checks. */
30 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */
31 | // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
32 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
33 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
34 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
35 | /* Additional Checks */
36 | // "noUnusedLocals": true, /* Report errors on unused locals. */
37 | // "noUnusedParameters": true, /* Report errors on unused parameters. */
38 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
39 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
40 | /* Module Resolution Options */
41 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
42 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
43 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
44 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
45 | // "typeRoots": [], /* List of folders to include type definitions from. */
46 | // "types": [], /* Type declaration files to be included in compilation. */
47 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
48 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
49 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
50 | /* Source Map Options */
51 | // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
52 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
53 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
54 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
55 | /* Experimental Options */
56 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
57 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
58 | }
59 | }
--------------------------------------------------------------------------------