Серверная часть. undefined Серверная часть.

Серверная часть.

Open in new window

Интернет-магазин. Серверная часть.

Разрабатываем серверную часть RESTfull API интернет-магазина штор.

Схема данных (PostgreSQL)

database

Задача - создать RESTfull API сервис, используя NodeJS.

Установка инструментов.

sudo apt install nodejs
sudo npm cache clean -f
sudo npm install -g n
sudo n stabl

Создадим каталог и инициализируем в нем пакет npm (package.json).

mkdir server
cd server
npm init

Установка npm зависимостей.

npm install express --save
npm install --save-dev @types/node ts-node typescript nodemon

tsconfig.json

{
    "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "outDir": "dist",
    "sourceMap": true
    },
    "include": [
    "src/**/*.ts"
    ],
    "exclude": [
    "node_modules",
    ".vscode"
    ]
}

Пишем простой сервер src/main.ts.

import * as express from "express";
const app = express();
app.get("/", (req, res) => {
    res.send("Hello World")
})
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
     console.log(`Server is running in http://localhost:${PORT}`)
})

Команды запуска package.json.

"scripts": {
    "start": "node --inspect=5858 -r ts-node/register ./src/main.ts",
    "start:watch": "nodemon",
    "build": "tsc"

Настройки nodemon.

  "nodemonConfig": {
    "ignore": [
      "**/*.test.ts",
      "**/*.spec.ts",
      ".git",
      "node_modules"
    ],
    "watch": [
      "src"
    ],
    "exec": "npm start",
    "ext": "ts"
  }

В exec мы указываем команду, которую мониторить.

Запуск сервера.

npm run start:watch

Работа с СУБД PostgreSQL.

Установка либы.

npm install --save pg

Коннект к базе.

const Pool = require('pg').Pool
const pool = new Pool({
  user: 'postgres',
  host: 'localhost',
  database: 'curtains',
  password: '1q2w3e',
  port: 5432,
})

Запрос и вывод всех категорий.

app.get("/", async (req, res) => {
     const result = await pool.query('SELECT * FROM shop_category ORDER BY id ASC')
     res.status(200).json(result.rows)
})

Результат.

database

Добавим подкатегории в вывод, сделав в цикле по одному запросу на каждую категорию.

app.get("/", async (req: Request, res: Response) => {
    const result = await pool.query('SELECT * FROM shop_category ORDER BY id ASC')
    for(let category of result.rows){
        const subcats = await pool.query(`SELECT * FROM shop_subcategory where category_id=${category.id}`)
        category.subcategories = subcats.rows;
    }
    res.status(200).json(result.rows)
})

Результат.

database

Делим на модули.

Создаем новый модуль src/api/category.ts

import {Request, Response} from "express";

export class CategoryAPI {
    put(req: Request, res: Response){}

    getAll(req: Request, res: Response){}

    getOne(req: Request, res: Response){}

    post(req: Request, res: Response){}

    delete(req: Request, res: Response){}
}

Применяем в главном модуле main.ts.

import { CategoryAPI } from './api/category';

const category_api = new CategoryAPI();
app.get("/category/all", category_api.getAll);
app.get("/category/one/:id", category_api.getOne);
app.delete("/category/delete/:id", category_api.delete);
app.post("/category/edit", category_api.post);
app.put("/category/create", category_api.put);

Выносим запрос в модуль.

import {Request, Response} from "express";
import pool from '../db';

export class CategoryAPI {
    put(req: Request, res: Response){}

    async getAll(req: Request, res: Response){

        const result = await pool.query('SELECT * FROM shop_category ORDER BY id ASC')

        for(let category of result.rows){
           const subcats = await pool.query(`SELECT * FROM shop_subcategory where category_id=${category.id}`)
           category.subcategories = subcats.rows;
       }

        res.status(200).json(result.rows)

    }

    getOne(req: Request, res: Response){}

    post(req: Request, res: Response){}

    delete(req: Request, res: Response){}
}

Выносим коннект к БД в db.ts.

const Pool = require('pg').Pool
const pool = new Pool({
  user: 'postgres',
  host: 'localhost',
  database: 'curtains',
  password: '1q2w3e',
  port: 5432,
})

export default pool;

Создадим класс для продуктов api/good.ts

import pool from '../db';
import {Request, Response} from "express";

class Good{
    id: number;
    name: string;
    name_slug: string;
    desc: string;
    subcategory_id: number;
    subcategory: any;
    image: any;

    constructor(){}

    public static async serialize(json_obj: any){
      let obj = new Good();
      obj.id = json_obj.id;
      obj.name = json_obj.name;
      obj.name_slug = json_obj.name_slug;
      obj.desc = json_obj.desc;
      obj.subcategory_id = json_obj.subcategory_id;
      return obj;
    }
  }


  export class GoodAPI {


    async getOne(req: Request, res: Response){

        const sql = 'SELECT * FROM shop_good where id=$1';
        const result = await pool.query(sql,[req.params.id]);
        let good = await Good.serialize(result.rows[0]);
        res.json(good);

    }

  }

Добавим роутинг.

import { GoodAPI } from './api/good';

const good_api = new GoodAPI();

app.get("/good/detail/:id", good_api.getOne);

Результат запроса на http://localhost:3000/good/detail/1.

database

Добавим выборку категорий и картинок.

database

Тестирование запросов на NodeJS.

Устанавливаем библиотеку jasmine:

npm install jasmine-core jasmine @types/jasmine jasmine-ts --save-dev

Request.

npm install --save-dev request @types/request

После установки инициируем папку spec c настройками jasmine командой

npm test init

Other topics