mirror of
https://github.com/sergeyyarkov/node-docker-example.git
synced 2026-10-11 10:19:41 +03:00
feat: server setup
This commit is contained in:
commit
11e01a24e4
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
node_modules
|
||||||
|
.env
|
||||||
1076
package-lock.json
generated
Normal file
1076
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
25
package.json
Normal file
25
package.json
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"name": "node-docker-example",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"start": "node server.js",
|
||||||
|
"dev": "nodemon server.js"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"nodejs",
|
||||||
|
"api",
|
||||||
|
"docker"
|
||||||
|
],
|
||||||
|
"author": "Sergey Yarkov",
|
||||||
|
"license": "ISC",
|
||||||
|
"devDependencies": {
|
||||||
|
"nodemon": "^2.0.15"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"dotenv": "^16.0.0",
|
||||||
|
"pg": "^8.7.3"
|
||||||
|
}
|
||||||
|
}
|
||||||
150
server.js
Normal file
150
server.js
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
import http from 'node:http';
|
||||||
|
import dotenv from 'dotenv';
|
||||||
|
import pg from 'pg';
|
||||||
|
|
||||||
|
class Database {
|
||||||
|
constructor() {
|
||||||
|
this.client = new pg.Client({
|
||||||
|
user: process.env.PG_USER,
|
||||||
|
host: process.env.PG_HOST,
|
||||||
|
database: process.env.PG_DB_NAME,
|
||||||
|
password: process.env.PG_PASSWORD,
|
||||||
|
port: process.env.PG_PORT,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Router {
|
||||||
|
constructor() {
|
||||||
|
/**
|
||||||
|
* Store the current list of routes for out API
|
||||||
|
*/
|
||||||
|
this.routes = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {http.ClientRequest} req
|
||||||
|
* @param {http.ServerResponse} res
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
call(req, res) {
|
||||||
|
if (this.routes.hasOwnProperty(req.url)) {
|
||||||
|
this.routes[req.url](req, res);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
define(url, handler) {
|
||||||
|
this.routes[url] = handler;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Response {
|
||||||
|
#req;
|
||||||
|
#res;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extends the http response object with this class
|
||||||
|
* @param {http.ClientRequest} req
|
||||||
|
* @param {http.ServerResponse} res
|
||||||
|
*/
|
||||||
|
constructor(req, res) {
|
||||||
|
this.#req = req;
|
||||||
|
this.#res = res;
|
||||||
|
}
|
||||||
|
|
||||||
|
send(text) {
|
||||||
|
this.#res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||||
|
this.#res.end(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
json(data, status = 200) {
|
||||||
|
this.#res.writeHead(status, { 'Content-Type': 'application/json' });
|
||||||
|
this.#res.end(JSON.stringify(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
notFound(data) {
|
||||||
|
this.json(data, 404);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Application {
|
||||||
|
constructor() {
|
||||||
|
this.booted = false;
|
||||||
|
|
||||||
|
this.config = this.#setupConfig();
|
||||||
|
this.server = http.createServer();
|
||||||
|
this.db = new Database();
|
||||||
|
this.router = new Router();
|
||||||
|
this.#connectDb(this.db.client).then(() => this.run());
|
||||||
|
}
|
||||||
|
|
||||||
|
run() {
|
||||||
|
this.#handle();
|
||||||
|
this.booted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#setupConfig() {
|
||||||
|
return {
|
||||||
|
config: dotenv.config(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will initialize the connection to Database
|
||||||
|
* @param {pg.Client} client
|
||||||
|
*/
|
||||||
|
async #connectDb(client) {
|
||||||
|
try {
|
||||||
|
await client.connect();
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#handle() {
|
||||||
|
this.server.on('request', (req, res) => {
|
||||||
|
const response = new Response(req, res);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reponse with API data
|
||||||
|
*/
|
||||||
|
if (req.url.includes('api')) {
|
||||||
|
const handled = this.router.call(req, response);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undefined route
|
||||||
|
*/
|
||||||
|
if (!handled) response.notFound({ data: 'Route not found!' });
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reponse with static files
|
||||||
|
*/
|
||||||
|
response.send('Static Page.');
|
||||||
|
});
|
||||||
|
this.server.listen(process.env.PORT, () =>
|
||||||
|
console.log(`Server is running on port "${process.env.PORT}"`)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const app = new Application();
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {http.ClientRequest} req
|
||||||
|
* @param {Response} res
|
||||||
|
*/
|
||||||
|
const getArticlesHandler = async (req, res) => {
|
||||||
|
res.json([
|
||||||
|
{ id: 1, title: 'First artcile' },
|
||||||
|
{ id: 2, title: 'Second artcile' },
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
app.router.define('/api/articles', getArticlesHandler);
|
||||||
Loading…
x
Reference in New Issue
Block a user