Thierry  Perret

Thierry Perret

1660303920

Comment Créer Des Points De Terminaison REST Avec Knex Et PostgreSQL

Dans ce blog, nous vous expliquerons comment créer des services basés sur REST à l'aide de Knex et PostgreSQL.

Qu'est-ce que Knex et PostgreSQL ?

Knex est un générateur de requêtes SQL polyvalent, portable et agréable pour PostgreSQL, CockroachDB, MSSQL, MySQL, MariaDB, SQLite3, Better-SQLite3, Oracle et Amazon Redshift, tandis que PostgreSQL est un système de gestion de base de données relationnelle objet open source avec un haut degré de flexibilité. Il est capable de gérer un large éventail de cas d'utilisation, y compris des machines uniques, des entrepôts de données et des services Web avec plusieurs utilisateurs simultanés. Il s'agit d'un système de gestion de base de données relationnelle qui utilise et étend SQL (d'où son nom), et il est largement extensible à une variété de cas d'utilisation au-delà des données transactionnelles.

PostgreSQL stocke les informations dans des tables (appelées relations) qui contiennent des tuples qui représentent des entités (telles que des documents et des personnes) et des relations (telles que la paternité). Les attributs de type fixe qui représentent des propriétés d'entité (telles qu'un titre), ainsi qu'une clé primaire, sont inclus dans les relations. Les types d'attributs peuvent être atomiques (par exemple, entier, virgule flottante ou booléen) ou structurés (comme un tableau, JSON imbriqué ou une procédure).

Pourquoi utiliser Knex ?

La plupart des développeurs utilisent Knex comme générateur de requêtes pour les raisons suivantes.

  • Il leur permet de créer des requêtes comme s'ils écrivaient du code Javascript, tout en gérant la traduction en SQL.
  • Il prend en charge les systèmes de gestion de bases de données tels que PostgreSQL, MySQL, SQLite et Oracle.
  • Il prend en charge à la fois les rappels traditionnels de style nœud et une interface promise pour un contrôle de flux asynchrone plus propre, ainsi qu'une interface de flux.
  • Il s'agit de constructeurs de requêtes et de schémas complets, d'une prise en charge des transactions (avec points de sauvegarde), d'un regroupement de connexions et de réponses standardisées entre les clients de requête et les dialectes.

Conditions préalables

Comme il s'agit d'un didacticiel de démonstration pratique, pour commencer, assurez-vous que vos systèmes répondent aux exigences suivantes :

  • Vous avez Node.js version 14 ou ultérieure installé
  • Vous avez installé et configuré Arctype
  • Vous avez configuré une base de données PostgreSQL
  • Installez le Knex CLI (la commande pour le faire est npm i -g knex)

Une fois les conditions ci-dessus remplies, créons une nouvelle base de données à l'aide d'Arctype. Pour commencer, lancez le client Arctype , puis choisissez la base de données avec laquelle vous souhaitez travailler :

Sélection du SGBD dans Arctype

Ensuite, fournissez les informations d'identification de la base de données en question. C'est très simple à faire, pas de soucis ici !

Définition des informations d'identification de la base de données

Si vous avez déjà configuré une base de données, vous pouvez toujours en créer une nouvelle en ajoutant une nouvelle source de données :

Ajouter une nouvelle source de données dans Arctype

Une fois que vous avez terminé, vous devriez voir des tables sous votre base de données sur le côté gauche d'Arctype.

Créer le serveur Node.js

Maintenant, créez un nouveau dossier pour votre projet et initialisez un nouveau projet avec les commandes ci-dessous.

mkdir knex-demo && cd knex-demo
npm init -y

Installez ensuite les packages requis en exécutant la commande suivante :

npm install pg express knex

Avec la commande ci-dessus, vous avez installé le module PostgreSQL Node.js express, et le knexmodule.

Créez maintenant la structure de dossiers suivante ci-dessous dans le dossier knex-demo.

📦knex-demo
┣ 📂src
┃ ┣ 📂config
┃ ┣ 📂controller
┃ ┣ 📂routes
┃ ┣ 📂service
┃ ┗ 📜app.js
┣ 📜package-lock.json
┗ 📜package.json

Ensuite, dans le app.jsfichier, créez un serveur Node.js Express avec l'extrait de code ci-dessous.

const express = require("express");   

const app = express();

app.use(express.json());

app.listen(3000, () => {
  console.log("Server is running on port 3000");
});

Enfin, modifiez le package.jsonfichier pour ajouter la commande de script.

 "scripts": {
    "start": "node src/app.js"
  },

Configurer Knex

Une fois que vous avez créé la base de données, configurons Knex et connectons-nous à la base de données. Pour commencer, exécutez la commande ci-dessous sur votre terminal pour initialiser knex.

knex init

La commande ci-dessus créera un knexfile.jsfichier dans le répertoire racine de votre projet avec les extraits de code pour connecter votre base de données à différents environnements (développement, staging, production.) Par défaut, il utilise la base de données SQLite dans l'environnement de développement, vous devrez modifier le code pour utiliser votre base de données Postgres.

// Update with your config settings.

/**
 * @type { Object.<string, import("knex").Knex.Config> }
 */
module.exports = {
  development: {
    client: "postgresql",
    connection: {
      database: "blogs",
      user: "postgres",
      password: "1234",
    },
  },

  staging: {
    client: "postgresql",
    connection: {
      database: "<Your Staging DB>",
      user: "username",
      password: "password",
    },
    pool: {
      min: 2,
      max: 10,
    },
    migrations: {
      tableName: "knex_migrations",
    },
  },

  production: {
    client: "postgresql",
    connection: {
      database: "<Your Production DB>",
      user: "username",
      password: "password",
    },
    pool: {
      min: 2,
      max: 10,
    },
    migrations: {
      tableName: "knex_migrations",
    },
  },
};

Votre knexfile.jsfichier devrait ressembler à l'extrait de code ci-dessus. Vous pouvez modifier le code pour répondre à toute autre exigence de projet que vous pourriez avoir.

Création du fichier de migration

Exécutez maintenant la commande ci-dessous pour créer votre fichier de migration pour la table de l'utilisateur et définissez à quoi ressemblera la table en exécutant la commande ci-dessous.

knex migrate:make users

La commande ci-dessus créera un migrations/timestamp_usersfichier dans le répertoire racine de votre projet. Définissons maintenant le schéma dans les fonctions ups et down.

/**
 * @param { import("knex").Knex } knex
 * @returns { Promise<void> }
 */
exports.up = function (knex) {
  return knex.schema.createTable("users", (table) => {
    table.increments("id").primary();
    table.string("name").notNullable();
    table.string("email").notNullable();
    table.string("password").notNullable();
    table.string("avatar").defaultTo("https://i.imgur.com/Xq2bZCY.png");
    table.string("bio").defaultTo("I am a new user");
    table.timestamp("created_at").defaultTo(knex.fn.now());
    table.timestamp("updated_at").defaultTo(knex.fn.now());
  });
};

/**
 * @param { import("knex").Knex } knex
 * @returns { Promise<void> }
 */
exports.down = function (knex) {
  return knex.schema.dropTable("users");
};

Le code dans le migrations/timestamp_users.jsfichier doit ressembler à l'extrait de code ci-dessus. Nous avons défini le schéma de l'utilisateur. Le premier est un idchamp avec une auto-incrémentation définie sur true et une contrainte unique, après quoi nous avons les champs dont nous avons besoin pour la table de l'utilisateur.

Ensuite, dans la downfonction, nous supprimons toute table existante portant le nom d' utilisateurs avant de créer notre nouvelle table.

Pour créer cette table dans votre base de données, vous devez exécuter à nouveau la commande migrations, cette fois vous devez ajouter l' latestindicateur pour valider uniquement les nouvelles modifications dans le fichier.

knex migrate:latest

Ensuite, créez le schéma des blogs en exécutant la commande de migration ci-dessous sur votre terminal.

knex migrate:make blogs

Ajoutez ensuite le code ci-dessous dans la fonction up pour définir le schéma du blog.

/**
 * @param { import("knex").Knex } knex
 * @returns { Promise<void> }
 */
exports.up = function (knex) {
  return knex.schema.createTable("blog", (table) => {
    table.increments("id").primary();
    table.string("title").notNullable();
    table.string("content").notNullable();
    table.string("image").notNullable();
    table.timestamp("created_at").defaultTo(knex.fn.now());
    table.timestamp("updated_at").defaultTo(knex.fn.now());
  });
};

/**
 * @param { import("knex").Knex } knex
 * @returns { Promise<void> }
 */
exports.down = function (knex) {
    return knex.schema.dropTable("blog");
};

Dans l'extrait de code ci-dessus, nous avons créé un schéma de blog et défini les champs dont nous avons besoin dans la table des blogs. Nous supprimons également toute table existante portant le nom blogs .

Création des relations de table

Créons maintenant une relation entre le schéma de l'utilisateur et le schéma du blog. De cette façon, nous pouvons associer les blogs aux utilisateurs qui les créent. Pour ce faire, nous devons mettre à jour le code dans le timestamps_blogs.jsfichier avec le code suivant :

/**
 * @param { import("knex").Knex } knex
 * @returns { Promise<void> }
 */
exports.up = function (knex) {
  return knex.schema.createTable("blog", (table) => {
    table.increments("id").primary();
    table.string("title").notNullable();
    table.string("content").notNullable();
    table.string("image").notNullable();
    table
      .integer("author")
      .unsigned()
      .references("id")
      .inTable("users")
      .onDelete("CASCADE");
    table.timestamp("created_at").defaultTo(knex.fn.now());
    table.timestamp("updated_at").defaultTo(knex.fn.now());
  });
};

/**
 * @param { import("knex").Knex } knex
 * @returns { Promise<void> }
 */
exports.down = function (knex) {
    return knex.schema.dropTable("blog");
};

Dans l'extrait de code ci-dessus, nous avons modifié le champ auteur pour référencer l'identifiant de chaque utilisateur dans le schéma de l'utilisateur. Le OnDeletetestament garantit que le blog est supprimé une fois le compte de l'utilisateur supprimé.

Ensuite, créez un db.jsfichier dans le dossier de configuration et ajoutez l'extrait de code ci-dessous.

const knex = require("knex");
const config = require("../../knexfile");
module.exports = knex(config.development);

Dans l'extrait de code ci-dessus, nous importons le configfrom knexfileet initialisons l'objet knex, donc depuis l'exécution de l'application sur l'environnement de développement, nous appellerons l' developmentobjet config.

Création du service

Une fois nos tables de base de données créées, créons un service qui effectue des opérations CRUD dans les tables de base de données. Créez un userService.jsfichier dans le servicedossier et ajoutez l'extrait de code spécifié ci-dessous.

const db = require('../config/db');

module.exports = userService = {
  getAll: async () => {
    const users = await db("users");
    return users;
  },
  getById: async (id) => {
    const user = await db("users").where("id", id);
    return user;
  },
  create: async (user) => {
    const users = await db("users").insert(user);
    return users;
  },
  update: async (id, user) => {
    const users = await db("users").where("id", id).update({
      name: user.name,
      email: user.email,
      password: user.password,
      avatar: user.avatar,
      bio: user.bio,
    });
    return users;
  },
  delete: async (id) => {
    const users = await db("users").where("id", id).del();
    return users;
  },
};

Dans l'extrait de code ci-dessus, nous avons importé la configuration knex. Ensuite, nous avons créé userServiceun objet et créé les méthodes pour les opérations CRUD.

Ensuite, créez un blogService.jsfichier dans le dossier de service et ajoutez l'extrait de code ci-dessous.

const db = require("../config/db");

module.exports = blogService = {
  getAll: async () => {
    const blogs = await db("blog")
      .join("users", "users.id", "blog.author")
      .select(
        "blog.*",
        "users.name",
        "users.avatar",
        "users.bio",
        "users.email"
      );
    return blogs;
  },
  getById: async (id) => {
    console.log(id);
    const blog = await db("blog").where({ id });
    return blog;
  },
  create: async (blog) => {
    const blogs = await db("blog").insert(blog);
    return blogs;
  },
  update: async (id, blog) => {
    const blogs = await db("blog").where("id", id).update({
      title: blog.title,
      content: blog.content,
      image: blog.image,
    });
    return blogs;
  },
  delete: async (id) => {
    const blogs = await db("blogs").where("id", id).del();
    return blogs;
  },
};

Dans l'extrait de code ci-dessus, nous avons créé les opérations CRUD pour le service blogService. Dans la getAllméthode, nous joignons la userstable à la blogstable, en utilisant la méthode select pour selectles champs que nous voulons montrer aux utilisateurs - si nous appelons maintenant le service, nous pouvons obtenir les blogs et les utilisateurs qui les ont publiés.

Création du contrôleur

Créons maintenant le contrôleur pour consommer le service que nous venons de créer. Commençons par le contrôleur de l'utilisateur. Créez donc un userController.jsfichier dans le dossier du contrôleur et ajoutez l'extrait de code ci-dessous.

const userService = require("../service/userService");
module.exports = userController = {
  getAll: async (req, res, next) => {
    try {
      const users = await userService.getAll();
      res.json(users);
    } catch (error) {
      next(error);
    }
  },
  getById: async (req, res, next) => {
    try {
      const user = await userService.getById(req.params.id);
      res.json(user);
    } catch (error) {
      next(error);
    }
  },
  create: async (req, res, next) => {
    try {
      const user = await userService.create(req.body);
      res.json(user);
    } catch (error) {
      next(error);
    }
  },
  update: async (req, res, next) => {
    try {
      const user = await userService.update(req.params.id, req.body);
      res.json(user);
    } catch (error) {
      next(error);
    }
  },
  delete: async (req, res, next) => {
    try {
      const user = await userService.delete(req.params.id);
      res.json(user);
    } catch (error) {
      next(error);
    }
  },
};

Créez maintenant un blogController.jsfichier dans le dossier du contrôleur pour utiliser l' blogServiceextrait de code ci-dessous.

const userService = require("../service/userService");
module.exports = userController = {
  getAll: async (req, res, next) => {
    try {
      const users = await userService.getAll();
      res.json(users);
    } catch (error) {
      next(error);
    }
  },
  getById: async (req, res, next) => {
    try {
      const user = await userService.getById(req.params.id);
      res.json(user);
    } catch (error) {
      next(error);
    }
  },
  create: async (req, res, next) => {
    try {
      const user = await userService.create(req.body);
      res.json(user);
    } catch (error) {
      next(error);
    }
  },
  update: async (req, res, next) => {
    try {
      const user = await userService.update(req.params.id, req.body);
      res.json(user);
    } catch (error) {
      next(error);
    }
  },
  delete: async (req, res, next) => {
    try {
      const user = await userService.delete(req.params.id);
      res.json(user);
    } catch (error) {
      next(error);
    }
  },
};

Création des routes d'API

Ensuite, créons les routes d'API pour les controllers . Pour commencer, créez un user.jsfichier dans le routesdossier et ajoutez l'extrait de code ci-dessous.

const express = require("express");
const router = express.Router();
const userController = require("../controller/userController");

/* GET users listing. */
router.route("/").get(userController.getAll).post(userController.create);
router
  .route("/:id")
  .get(userController.getById)
  .put(userController.update)
  .delete(userController.delete);

module.exports = router;

Dans l'extrait de code ci-dessus, nous avons importé userControlleret créé un routeur express. En utilisant le routeur express, nous définissons les gestionnaires de route pour les contrôleurs.

Créez maintenant un autre fichier appelé blog.jsdans le dossier routes pour définir les gestionnaires de route pour le contrôleur de blog avec l'extrait de code ci-dessous.

const express = require("express");
const router = express.Router();
const blogController = require("../controller/blogController");

/* GET home page. */
router.route("/").get(blogController.getAll).post(blogController.create);
router
  .route("/:id")
  .get(blogController.getById)
  .put(blogController.update)
  .delete(blogController.delete);

module.exports = router;

Enfin, importez les routes dans le fichier app.js et créez un middleware pour les deux routes avec l'extrait de code ci-dessous.

...
const userRouter = require("./routes/users");
const blogRouter = require("./routes/blog"); 

...
app.use('/users', userRouter);
app.use('/blog', blogRouter);\

...

Tester l'API

Testons maintenant le projet pour nous assurer que tout fonctionne comme prévu. Tout d'abord, démarrez votre serveur avec la commande ci-dessous.

npm start

Lancez ensuite Postman ou tout autre outil de test d'API de votre choix.

Le point de terminaison utilisateur

Envoyez une demande POSTlocalhost:3000/users au point de terminaison avec la charge utile ci-dessous pour créer un utilisateur.

{
  "name":"name",
  "email":"name@gmail.com",
  "password":"1234",
  "bio":"I am a software dev."
}

Test du point de terminaison utilisateur - Résultats

Ensuite, envoyez une requête GET au même point de terminaison pour obtenir tous les utilisateurs enregistrés. Allez-y et testez les points de terminaison de l'autre utilisateur.

Obtenir tous les utilisateurs enregistrés - Résultats

Le point de terminaison du blog

Envoyez maintenant une requête POST au point de terminaison localhost:3000/blogavec la charge utile ci-dessous pour créer un blog pour l'utilisateur avec l' identifiant 1 indiqué par le champ auteur .

{
    "title":"My First Blog",
    "content":"Blah Blah Blah",
    "image":"Image URL",
    "author":"1"
}

Test du point de terminaison de blog - requête POST

Envoyez ensuite une requête GET au même point de terminaison pour obtenir tous les blogs.

Test du point de terminaison de blog - Requête GET

Affichage des données utilisateur avec Arctype

Nous avons maintenant créé avec succès notre application Blog. Examinons maintenant les données des utilisateurs avec Arctype. Pour commencer, lancez Arctype, cliquez sur l' Postgresonglet et entrez les Postgresinformations d'identification suivantes, comme indiqué dans la capture d'écran ci-dessous (c'est la même chose que nous avons fait avec MySQL au début) :

Vous devriez voir la table user , blog et les tables de migrations knex enregistrer les migrations effectuées dans l'application. Cliquez maintenant sur le tableau des blogs pour afficher les blogs de l'utilisateur, comme indiqué dans la capture d'écran ci-dessous :

Les données PostgreSQL dans Arctype

Conclusion

En créant un projet de démonstration, nous avons appris à créer des points de terminaison REST avec Knex et PostgreSQL. Nous avons commencé par présenter PostgreSQL et Knex et pourquoi vous devriez les utiliser, puis nous avons créé un projet de blog pour la démonstration. Maintenant que vous avez acquis les connaissances que vous recherchez, comment utiliseriez-vous un générateur de requêtes dans votre prochain projet ? Envisagez d'en savoir plus sur Knex sur leur site officiel et allez encore plus loin !

Lien : https://arctype.com/blog/postgresql-rest-api-knex/

#restapi #api #postgresql #knex

Comment Créer Des Points De Terminaison REST Avec Knex Et PostgreSQL
高橋  陽子

高橋 陽子

1660293060

如何使用 Knex 和 PostgreSQL 構建 REST 端點

在本博客中,我們將告訴您應該如何使用 Knex 和 PostgreSQL 構建基於 REST 的服務。

什麼是 Knex 和 PostgreSQL?

Knex 是一個多功能、可移植且令人愉悅的 SQL 查詢構建器,適用於 PostgreSQL、CockroachDB、MSSQL、MySQL、MariaDB、SQLite3、Better-SQLite3、Oracle 和 Amazon Redshift,而 PostgreSQL 是一個開源對象關係數據庫管理系統,具有高度的靈活性。它能夠處理廣泛的用例,包括單機、數據倉庫和具有多個並髮用戶的 Web 服務。它是一個使用和擴展 SQL(因此得名)的關係數據庫管理系統,它可以廣泛地擴展到事務數據之外的各種用例。

PostgreSQL 將信息存儲在表中(稱為關係),其中包含表示實體(如文檔和人員)和關係(如作者身份)的元組。表示實體屬性(例如標題)以及主鍵的固定類型屬性包含在關係中。屬性類型可以是原子的(例如整數、浮點數或布爾值)或結構化的(例如數組、嵌套 JSON 或過程)。

為什麼使用 Knex?

大多數開發人員使用 Knex 作為他們的查詢構建器,原因如下。

  • 它允許他們像編寫 Javascript 代碼一樣創建查詢,同時處理 SQL 的轉換。
  • 它支持 PostgreSQL、MySQL、SQLite 和 Oracle 等數據庫管理系統。
  • 它支持傳統的節點樣式回調和用於更清晰的異步流控制的 Promise 接口,以及流接口。
  • 它是功能齊全的查詢和模式構建器、事務支持(帶有保存點)、連接池以及查詢客戶端和方言之間的標準化響應。

先決條件

由於這是一個動手演示教程,因此要開始使用,請確保您的系統滿足以下要求:

  • 您已安裝 Node.js 版本 14 或更高版本
  • 您已安裝並設置Arctype
  • 您已經建立了一個 PostgreSQL 數據庫
  • 安裝 Knex CLI(執行此操作的命令是npm i -g knex

滿足上述要求後,讓我們使用 Arctype 創建一個新數據庫。要開始啟動Arctype 客戶端,然後選擇您要使用的數據庫:

在 Arctype 中選擇 DBMS

然後提供相關數據庫的憑據。這一切都很簡單,在這裡沒有麻煩!

定義數據庫憑證

如果您已經設置了數據庫,則始終可以通過添加新數據源來創建新數據庫:

在 Arctype 中添加新數據源

完成後,您應該會在 Arctype 的左側看到數據庫下方的表格。

創建 Node.js 服務器

現在,為您的項目創建一個新文件夾並使用以下命令初始化一個新項目。

mkdir knex-demo && cd knex-demo
npm init -y

然後通過運行以下命令安裝所需的軟件包:

npm install pg express knex

使用上述命令,您已經安裝了 PostgreSQL Node.js 模塊express,以及該knex模塊。

現在在 knex-demo 文件夾中創建以下文件夾結構。

📦knex-demo
┣ 📂src
┃ ┣ 📂config
┃ ┣ 📂controller
┃ ┣ 📂routes
┃ ┣ 📂service
┃ ┗ 📜app.js
┣ 📜package-lock.json
┗ 📜package.json

然後在app.js文件中,使用下面的代碼片段創建一個 Node.js Express 服務器。

const express = require("express");   

const app = express();

app.use(express.json());

app.listen(3000, () => {
  console.log("Server is running on port 3000");
});

最後,修改package.json文件以添加腳本命令。

 "scripts": {
    "start": "node src/app.js"
  },

設置 Knex

創建數據庫後,讓我們設置 Knex 並連接到數據庫。首先,在終端上運行以下命令來初始化 knex。

knex init

上面的命令將在您的項目根目錄中創建一個knexfile.js文件,其中包含代碼片段,以將您的數據庫連接到不同的環境(開發、登台、生產)。默認情況下,它在開發環境中使用 SQLite 數據庫,您需要修改使用 Postgres 數據庫的代碼。

// Update with your config settings.

/**
 * @type { Object.<string, import("knex").Knex.Config> }
 */
module.exports = {
  development: {
    client: "postgresql",
    connection: {
      database: "blogs",
      user: "postgres",
      password: "1234",
    },
  },

  staging: {
    client: "postgresql",
    connection: {
      database: "<Your Staging DB>",
      user: "username",
      password: "password",
    },
    pool: {
      min: 2,
      max: 10,
    },
    migrations: {
      tableName: "knex_migrations",
    },
  },

  production: {
    client: "postgresql",
    connection: {
      database: "<Your Production DB>",
      user: "username",
      password: "password",
    },
    pool: {
      min: 2,
      max: 10,
    },
    migrations: {
      tableName: "knex_migrations",
    },
  },
};

您的knexfile.js文件應該類似於上面的代碼片段。您可以修改代碼以滿足您可能擁有的任何其他項目要求。

創建遷移文件

現在運行以下命令為用戶表創建遷移文件,並通過運行以下命令定義表的外觀。

knex migrate:make users

migrations/timestamp_users上面的命令將在項目的根目錄中創建一個文件。現在讓我們在 ups 和 down 函數中定義模式。

/**
 * @param { import("knex").Knex } knex
 * @returns { Promise<void> }
 */
exports.up = function (knex) {
  return knex.schema.createTable("users", (table) => {
    table.increments("id").primary();
    table.string("name").notNullable();
    table.string("email").notNullable();
    table.string("password").notNullable();
    table.string("avatar").defaultTo("https://i.imgur.com/Xq2bZCY.png");
    table.string("bio").defaultTo("I am a new user");
    table.timestamp("created_at").defaultTo(knex.fn.now());
    table.timestamp("updated_at").defaultTo(knex.fn.now());
  });
};

/**
 * @param { import("knex").Knex } knex
 * @returns { Promise<void> }
 */
exports.down = function (knex) {
  return knex.schema.dropTable("users");
};

文件中的代碼migrations/timestamp_users.js應該類似於上面的代碼片段。我們定義了用戶的模式。第一個是id自動增量設置為 true 和唯一約束的字段,之後我們擁有用戶表所需的字段。

然後在函數中,我們在創建新表之前刪除任何名稱為usersdown的現有表。

要在數據庫中創建此表,您需要再次運行遷移命令,這次您需要添加latest標誌以僅提交文件中的新更改。

knex migrate:latest

接下來,通過在終端上運行以下遷移命令來創建博客架構。

knex migrate:make blogs

然後在up函數中添加下面的代碼來定義博客的架構。

/**
 * @param { import("knex").Knex } knex
 * @returns { Promise<void> }
 */
exports.up = function (knex) {
  return knex.schema.createTable("blog", (table) => {
    table.increments("id").primary();
    table.string("title").notNullable();
    table.string("content").notNullable();
    table.string("image").notNullable();
    table.timestamp("created_at").defaultTo(knex.fn.now());
    table.timestamp("updated_at").defaultTo(knex.fn.now());
  });
};

/**
 * @param { import("knex").Knex } knex
 * @returns { Promise<void> }
 */
exports.down = function (knex) {
    return knex.schema.dropTable("blog");
};

在上面的代碼片段中,我們創建了一個博客模式,並在 blogs 表中定義了我們需要的字段。我們還將刪除名稱為blogs的任何現有表。

創建表關係

現在讓我們在用戶架構和博客架構之間創建關係。通過這種方式,我們可以將博客與創建它們的用戶相關聯。為此,我們需要timestamps_blogs.js使用以下代碼更新文件中的代碼:

/**
 * @param { import("knex").Knex } knex
 * @returns { Promise<void> }
 */
exports.up = function (knex) {
  return knex.schema.createTable("blog", (table) => {
    table.increments("id").primary();
    table.string("title").notNullable();
    table.string("content").notNullable();
    table.string("image").notNullable();
    table
      .integer("author")
      .unsigned()
      .references("id")
      .inTable("users")
      .onDelete("CASCADE");
    table.timestamp("created_at").defaultTo(knex.fn.now());
    table.timestamp("updated_at").defaultTo(knex.fn.now());
  });
};

/**
 * @param { import("knex").Knex } knex
 * @returns { Promise<void> }
 */
exports.down = function (knex) {
    return knex.schema.dropTable("blog");
};

在上面的代碼片段中,我們修改了 author 字段以引用用戶架構中每個用戶的 id。遺囑確保一旦用戶帳戶被刪除,OnDelete博客就會被刪除。

接下來,在 config 文件夾中創建一個db.js文件並添加下面的代碼片段。

const knex = require("knex");
const config = require("../../knexfile");
module.exports = knex(config.development);

在上面的代碼片段中,我們正在導入configfromknexfile並初始化 knex 對象,因此由於在開發環境中運行應用程序,我們將調用developmentconfig 對象。

創建服務

創建數據庫表後,讓我們創建一個在數據庫表中執行 CRUD 操作的服務。在文件夾中創建一個userService.js文件service並添加下面指定的代碼片段。

const db = require('../config/db');

module.exports = userService = {
  getAll: async () => {
    const users = await db("users");
    return users;
  },
  getById: async (id) => {
    const user = await db("users").where("id", id);
    return user;
  },
  create: async (user) => {
    const users = await db("users").insert(user);
    return users;
  },
  update: async (id, user) => {
    const users = await db("users").where("id", id).update({
      name: user.name,
      email: user.email,
      password: user.password,
      avatar: user.avatar,
      bio: user.bio,
    });
    return users;
  },
  delete: async (id) => {
    const users = await db("users").where("id", id).del();
    return users;
  },
};

在上面的代碼片段中,我們導入了 knex 配置。然後我們創建了userService對象並創建了 CRUD 操作的方法。

blogService.js接下來,在服務文件夾中創建一個文件並添加下面的代碼片段。

const db = require("../config/db");

module.exports = blogService = {
  getAll: async () => {
    const blogs = await db("blog")
      .join("users", "users.id", "blog.author")
      .select(
        "blog.*",
        "users.name",
        "users.avatar",
        "users.bio",
        "users.email"
      );
    return blogs;
  },
  getById: async (id) => {
    console.log(id);
    const blog = await db("blog").where({ id });
    return blog;
  },
  create: async (blog) => {
    const blogs = await db("blog").insert(blog);
    return blogs;
  },
  update: async (id, blog) => {
    const blogs = await db("blog").where("id", id).update({
      title: blog.title,
      content: blog.content,
      image: blog.image,
    });
    return blogs;
  },
  delete: async (id) => {
    const blogs = await db("blogs").where("id", id).del();
    return blogs;
  },
};

在上面的代碼片段中,我們為服務 blogService 創建了 CRUD 操作。在該getAll方法中,我們將users表格與blogs表格連接起來,使用 select 方法連接到select我們想要向用戶顯示的字段 - 如果我們現在調用該服務,我們可以獲得博客和發布它們的用戶。

創建控制器

現在讓我們創建控制器來使用我們剛剛創建的服務。讓我們從用戶的控制器開始。userController.js因此,在控制器文件夾中創建一個文件並添加下面的代碼片段。

const userService = require("../service/userService");
module.exports = userController = {
  getAll: async (req, res, next) => {
    try {
      const users = await userService.getAll();
      res.json(users);
    } catch (error) {
      next(error);
    }
  },
  getById: async (req, res, next) => {
    try {
      const user = await userService.getById(req.params.id);
      res.json(user);
    } catch (error) {
      next(error);
    }
  },
  create: async (req, res, next) => {
    try {
      const user = await userService.create(req.body);
      res.json(user);
    } catch (error) {
      next(error);
    }
  },
  update: async (req, res, next) => {
    try {
      const user = await userService.update(req.params.id, req.body);
      res.json(user);
    } catch (error) {
      next(error);
    }
  },
  delete: async (req, res, next) => {
    try {
      const user = await userService.delete(req.params.id);
      res.json(user);
    } catch (error) {
      next(error);
    }
  },
};

blogController.js現在在控制器文件夾中創建一個文件來使用blogService下面的代碼片段。

const userService = require("../service/userService");
module.exports = userController = {
  getAll: async (req, res, next) => {
    try {
      const users = await userService.getAll();
      res.json(users);
    } catch (error) {
      next(error);
    }
  },
  getById: async (req, res, next) => {
    try {
      const user = await userService.getById(req.params.id);
      res.json(user);
    } catch (error) {
      next(error);
    }
  },
  create: async (req, res, next) => {
    try {
      const user = await userService.create(req.body);
      res.json(user);
    } catch (error) {
      next(error);
    }
  },
  update: async (req, res, next) => {
    try {
      const user = await userService.update(req.params.id, req.body);
      res.json(user);
    } catch (error) {
      next(error);
    }
  },
  delete: async (req, res, next) => {
    try {
      const user = await userService.delete(req.params.id);
      res.json(user);
    } catch (error) {
      next(error);
    }
  },
};

創建 API 路由

接下來,讓我們為控制器創建 API 路由。首先,user.js在文件夾中創建一個文件routes並添加下面的代碼片段。

const express = require("express");
const router = express.Router();
const userController = require("../controller/userController");

/* GET users listing. */
router.route("/").get(userController.getAll).post(userController.create);
router
  .route("/:id")
  .get(userController.getById)
  .put(userController.update)
  .delete(userController.delete);

module.exports = router;

在上面的代碼片段中,我們已經導入userController並創建了一個快速路由器。使用 express 路由器,我們為控制器定義路由處理程序。

現在創建另一個名為blog.jsroutes 文件夾的文件,以使用下面的代碼片段為博客控制器定義路由處理程序。

const express = require("express");
const router = express.Router();
const blogController = require("../controller/blogController");

/* GET home page. */
router.route("/").get(blogController.getAll).post(blogController.create);
router
  .route("/:id")
  .get(blogController.getById)
  .put(blogController.update)
  .delete(blogController.delete);

module.exports = router;

最後,在 app.js 文件中導入路由,並使用下面的代碼片段為這兩個路由創建一個中間件。

...
const userRouter = require("./routes/users");
const blogRouter = require("./routes/blog"); 

...
app.use('/users', userRouter);
app.use('/blog', blogRouter);\

...

測試 API

現在讓我們測試項目以確保一切都按預期工作。首先,使用以下命令啟動 y0ur 服務器。

npm start

然後啟動 Postman 或您選擇的任何 API 測試工具。

用戶端點

使用以下負載向端點發送POST請求以localhost:3000/users創建用戶。

{
  "name":"name",
  "email":"name@gmail.com",
  "password":"1234",
  "bio":"I am a software dev."
}

測試用戶端點 - 結果

接下來,向同一端點發送GET請求以獲取所有註冊用戶。繼續測試其他用戶的端點。

獲取所有註冊用戶 - 結果

博客端點

現在使用下面的有效負載向端點發送POST請求,localhost:3000/blog為用戶創建一個博客,該用戶的id為 1,由author字段表示。

{
    "title":"My First Blog",
    "content":"Blah Blah Blah",
    "image":"Image URL",
    "author":"1"
}

測試博客端點 - POST 請求

然後向同一端點發送GET請求以獲取所有博客。

測試博客端點 - GET 請求

使用 Arctype 查看用戶數據

我們現在已經成功地創建了我們的博客應用程序。現在,讓我們用 Arctype 來看看用戶的數據。首先,啟動 Arctype,單擊Postgres選項卡,然後輸入以下Postgres憑據,如下面的屏幕截圖所示(與我們在開始時使用 MySQL 所做的一切相同):

您應該看到userblog表和 knex 遷移表記錄了應用程序中的遷移。現在點擊 blogs 表來顯示用戶的博客,如下圖所示:

Arctype 中的 PostgreSQL 數據

結論

通過構建一個演示項目,我們學習瞭如何使用 Knex 和 PostgreSQL 構建 REST 端點。我們首先介紹了 PostgreSQL 和 Knex 以及為什麼要使用它們,然後我們創建了一個博客項目來進行演示。現在您已經獲得了所需的知識,您將如何在下一個項目中使用查詢構建器?考慮從他們的官方網站了解更多關於Knex的信息,並更進一步!

鏈接:https ://arctype.com/blog/postgresql-rest-api-knex/

#restapi #api #postgresql #knex

如何使用 Knex 和 PostgreSQL 構建 REST 端點

Как создавать конечные точки REST с помощью Knex и PostgreSQL

В этом блоге мы расскажем вам, как создавать службы на основе REST с использованием Knex и PostgreSQL.

Что такое Knex и PostgreSQL?

Knex — это универсальный, портативный и приятный конструктор SQL-запросов для PostgreSQL, CockroachDB, MSSQL, MySQL, MariaDB, SQLite3, Better-SQLite3, Oracle и Amazon Redshift, а PostgreSQL — это система управления объектно-реляционными базами данных с открытым исходным кодом с высокая степень гибкости. Он способен обрабатывать широкий спектр вариантов использования, включая отдельные машины, хранилища данных и веб-сервисы с несколькими одновременными пользователями. Это система управления реляционной базой данных, которая использует и расширяет SQL (отсюда и название) и широко расширяема для различных вариантов использования, помимо транзакционных данных.

PostgreSQL хранит информацию в таблицах (называемых отношениями), которые содержат кортежи, представляющие сущности (например, документы и людей) и отношения (например, авторство). Атрибуты фиксированного типа, которые представляют свойства объекта (например, заголовок), а также первичный ключ, включаются в отношения. Типы атрибутов могут быть атомарными (например, целым числом, с плавающей запятой или логическим значением) или структурированными (например, массивом, вложенным JSON или процедурой).

Зачем использовать Кекс?

Большинство разработчиков используют Knex в качестве построителя запросов по следующим причинам.

  • Это позволяет им создавать запросы так же, как они пишут код Javascript, в то время как он обрабатывает преобразование в SQL.
  • Он поддерживает такие системы управления базами данных, как PostgreSQL, MySQL, SQLite и Oracle.
  • Он поддерживает как традиционные обратные вызовы в стиле узла, так и обещанный интерфейс для более чистого асинхронного управления потоком, а также потоковый интерфейс.
  • Это полнофункциональные построители запросов и схем, поддержка транзакций (с точками сохранения), объединение соединений и стандартизированные ответы между клиентами запросов и диалектами.

Предпосылки

Поскольку это практическое демонстрационное руководство, для начала убедитесь, что ваши системы соответствуют следующим требованиям:

  • У вас установлен Node.js версии 14 или новее.
  • Вы установили и настроили Arctype
  • Вы настроили базу данных PostgreSQL
  • Установите Knex CLI (команда для этого npm i -g knex)

Выполнив вышеуказанные требования, давайте создадим новую базу данных с помощью Arctype. Для начала запустите клиент Arctype , затем выберите базу данных, с которой вы хотите работать:

Выбор СУБД в Arctype

Затем укажите учетные данные соответствующей базы данных. Здесь все очень просто, никаких хлопот!

Определение учетных данных базы данных

Если у вас уже настроена база данных, вы всегда можете создать новую, добавив новый источник данных:

Добавление нового источника данных в Arctype

После того, как вы закончите, вы должны увидеть таблицы под вашей базой данных с левой стороны в Arctype.

Создайте сервер Node.js

Теперь создайте новую папку для своего проекта и инициализируйте новый проект с помощью приведенных ниже команд.

mkdir knex-demo && cd knex-demo
npm init -y

Затем установите необходимые пакеты, выполнив следующую команду:

npm install pg express knex

С помощью приведенной выше команды вы установили модуль PostgreSQL Node.js express, и knexмодуль.

Теперь создайте следующую структуру папок ниже в папке knex-demo.

📦knex-demo
┣ 📂src
┃ ┣ 📂config
┃ ┣ 📂controller
┃ ┣ 📂routes
┃ ┣ 📂service
┃ ┗ 📜app.js
┣ 📜package-lock.json
┗ 📜package.json

Затем в app.jsфайле создайте сервер Node.js Express с приведенным ниже фрагментом кода.

const express = require("express");   

const app = express();

app.use(express.json());

app.listen(3000, () => {
  console.log("Server is running on port 3000");
});

Наконец, измените package.jsonфайл, чтобы добавить команду сценария.

 "scripts": {
    "start": "node src/app.js"
  },

Настройка Кнекса

После того, как вы создали базу данных, давайте настроим Knex и подключимся к базе данных. Чтобы начать, выполните приведенную ниже команду на своем терминале, чтобы инициализировать knex.

knex init

Приведенная выше команда создаст knexfile.jsфайл в корневом каталоге вашего проекта с фрагментами кода для подключения вашей базы данных к различным средам (разработка, подготовка, производство). По умолчанию она использует базу данных SQLite в среде разработки, вам нужно изменить код для использования вашей базы данных Postgres.

// Update with your config settings.

/**
 * @type { Object.<string, import("knex").Knex.Config> }
 */
module.exports = {
  development: {
    client: "postgresql",
    connection: {
      database: "blogs",
      user: "postgres",
      password: "1234",
    },
  },

  staging: {
    client: "postgresql",
    connection: {
      database: "<Your Staging DB>",
      user: "username",
      password: "password",
    },
    pool: {
      min: 2,
      max: 10,
    },
    migrations: {
      tableName: "knex_migrations",
    },
  },

  production: {
    client: "postgresql",
    connection: {
      database: "<Your Production DB>",
      user: "username",
      password: "password",
    },
    pool: {
      min: 2,
      max: 10,
    },
    migrations: {
      tableName: "knex_migrations",
    },
  },
};

Ваш knexfile.jsфайл должен выглядеть как фрагмент кода выше. Вы можете изменить код, чтобы он соответствовал любым другим требованиям проекта, которые могут у вас возникнуть.

Создание файла миграции

Теперь запустите приведенную ниже команду, чтобы создать файл миграции для пользовательской таблицы и определить, как будет выглядеть таблица, выполнив приведенную ниже команду.

knex migrate:make users

Приведенная выше команда создаст migrations/timestamp_usersфайл в корневом каталоге вашего проекта. Теперь давайте определим схему в функциях ups и down.

/**
 * @param { import("knex").Knex } knex
 * @returns { Promise<void> }
 */
exports.up = function (knex) {
  return knex.schema.createTable("users", (table) => {
    table.increments("id").primary();
    table.string("name").notNullable();
    table.string("email").notNullable();
    table.string("password").notNullable();
    table.string("avatar").defaultTo("https://i.imgur.com/Xq2bZCY.png");
    table.string("bio").defaultTo("I am a new user");
    table.timestamp("created_at").defaultTo(knex.fn.now());
    table.timestamp("updated_at").defaultTo(knex.fn.now());
  });
};

/**
 * @param { import("knex").Knex } knex
 * @returns { Promise<void> }
 */
exports.down = function (knex) {
  return knex.schema.dropTable("users");
};

Код в migrations/timestamp_users.jsфайле должен выглядеть как приведенный выше фрагмент кода. Мы определили схему пользователя. Первое — это idполе с автоинкрементом, установленным в true, и уникальным ограничением, после этого у нас есть поля, которые нам нужны для пользовательской таблицы.

Затем в downфункции мы удаляем любую существующую таблицу с именем users, прежде чем создавать нашу новую таблицу.

Чтобы создать эту таблицу в своей базе данных, вам нужно снова запустить команду миграции, на этот раз вам нужно добавить latestфлаг, чтобы зафиксировать только новые изменения в файле.

knex migrate:latest

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

knex migrate:make blogs

Затем добавьте приведенный ниже код в функцию up , чтобы определить схему блога.

/**
 * @param { import("knex").Knex } knex
 * @returns { Promise<void> }
 */
exports.up = function (knex) {
  return knex.schema.createTable("blog", (table) => {
    table.increments("id").primary();
    table.string("title").notNullable();
    table.string("content").notNullable();
    table.string("image").notNullable();
    table.timestamp("created_at").defaultTo(knex.fn.now());
    table.timestamp("updated_at").defaultTo(knex.fn.now());
  });
};

/**
 * @param { import("knex").Knex } knex
 * @returns { Promise<void> }
 */
exports.down = function (knex) {
    return knex.schema.dropTable("blog");
};

В приведенном выше фрагменте кода мы создали схему блога и определили необходимые поля в таблице блогов. Мы также удаляем все существующие таблицы с именем blogs .

Создание отношений между таблицами

Теперь давайте создадим связь между схемой пользователя и схемой блога. Таким образом, мы можем связать блоги с пользователями, которые их создают. Для этого нам нужно обновить код в timestamps_blogs.jsфайле следующим кодом:

/**
 * @param { import("knex").Knex } knex
 * @returns { Promise<void> }
 */
exports.up = function (knex) {
  return knex.schema.createTable("blog", (table) => {
    table.increments("id").primary();
    table.string("title").notNullable();
    table.string("content").notNullable();
    table.string("image").notNullable();
    table
      .integer("author")
      .unsigned()
      .references("id")
      .inTable("users")
      .onDelete("CASCADE");
    table.timestamp("created_at").defaultTo(knex.fn.now());
    table.timestamp("updated_at").defaultTo(knex.fn.now());
  });
};

/**
 * @param { import("knex").Knex } knex
 * @returns { Promise<void> }
 */
exports.down = function (knex) {
    return knex.schema.dropTable("blog");
};

В приведенном выше фрагменте кода мы изменили поле автора, чтобы оно ссылалось на идентификатор каждого пользователя в пользовательской схеме. OnDeleteЗавещание гарантирует удаление блога после удаления учетной записи пользователя .

Затем создайте db.jsфайл в папке конфигурации и добавьте приведенный ниже фрагмент кода.

const knex = require("knex");
const config = require("../../knexfile");
module.exports = knex(config.development);

В приведенном выше фрагменте кода мы импортируем configи knexfileинициализируем объект knex, поэтому после запуска приложения в среде разработки мы будем вызывать developmentобъект конфигурации.

Создание службы

Создав наши таблицы базы данных, давайте создадим службу, которая выполняет операции CRUD в таблицах базы данных. Создайте userService.jsфайл в serviceпапке и добавьте фрагмент кода, указанный ниже.

const db = require('../config/db');

module.exports = userService = {
  getAll: async () => {
    const users = await db("users");
    return users;
  },
  getById: async (id) => {
    const user = await db("users").where("id", id);
    return user;
  },
  create: async (user) => {
    const users = await db("users").insert(user);
    return users;
  },
  update: async (id, user) => {
    const users = await db("users").where("id", id).update({
      name: user.name,
      email: user.email,
      password: user.password,
      avatar: user.avatar,
      bio: user.bio,
    });
    return users;
  },
  delete: async (id) => {
    const users = await db("users").where("id", id).del();
    return users;
  },
};

В приведенном выше фрагменте кода мы импортировали конфигурацию knex. Затем мы создали userServiceобъект и создали методы для операций CRUD.

Затем создайте blogService.jsфайл в папке службы и добавьте приведенный ниже фрагмент кода.

const db = require("../config/db");

module.exports = blogService = {
  getAll: async () => {
    const blogs = await db("blog")
      .join("users", "users.id", "blog.author")
      .select(
        "blog.*",
        "users.name",
        "users.avatar",
        "users.bio",
        "users.email"
      );
    return blogs;
  },
  getById: async (id) => {
    console.log(id);
    const blog = await db("blog").where({ id });
    return blog;
  },
  create: async (blog) => {
    const blogs = await db("blog").insert(blog);
    return blogs;
  },
  update: async (id, blog) => {
    const blogs = await db("blog").where("id", id).update({
      title: blog.title,
      content: blog.content,
      image: blog.image,
    });
    return blogs;
  },
  delete: async (id) => {
    const blogs = await db("blogs").where("id", id).del();
    return blogs;
  },
};

В приведенном выше фрагменте кода мы создали операции CRUD для сервиса blogService. В getAllметоде мы соединяем usersтаблицу с blogsтаблицей, используя метод select для selectполей, которые мы хотим показать пользователям — если мы сейчас вызовем службу, мы сможем получить блоги и пользователей, которые их опубликовали.

Создание контроллера

Теперь давайте создадим контроллер для использования только что созданной службы. Начнем с контроллера пользователя. Поэтому создайте userController.jsфайл в папке контроллера и добавьте приведенный ниже фрагмент кода.

const userService = require("../service/userService");
module.exports = userController = {
  getAll: async (req, res, next) => {
    try {
      const users = await userService.getAll();
      res.json(users);
    } catch (error) {
      next(error);
    }
  },
  getById: async (req, res, next) => {
    try {
      const user = await userService.getById(req.params.id);
      res.json(user);
    } catch (error) {
      next(error);
    }
  },
  create: async (req, res, next) => {
    try {
      const user = await userService.create(req.body);
      res.json(user);
    } catch (error) {
      next(error);
    }
  },
  update: async (req, res, next) => {
    try {
      const user = await userService.update(req.params.id, req.body);
      res.json(user);
    } catch (error) {
      next(error);
    }
  },
  delete: async (req, res, next) => {
    try {
      const user = await userService.delete(req.params.id);
      res.json(user);
    } catch (error) {
      next(error);
    }
  },
};

Теперь создайте blogController.jsфайл в папке контроллераblogService , чтобы использовать фрагмент кода ниже.

const userService = require("../service/userService");
module.exports = userController = {
  getAll: async (req, res, next) => {
    try {
      const users = await userService.getAll();
      res.json(users);
    } catch (error) {
      next(error);
    }
  },
  getById: async (req, res, next) => {
    try {
      const user = await userService.getById(req.params.id);
      res.json(user);
    } catch (error) {
      next(error);
    }
  },
  create: async (req, res, next) => {
    try {
      const user = await userService.create(req.body);
      res.json(user);
    } catch (error) {
      next(error);
    }
  },
  update: async (req, res, next) => {
    try {
      const user = await userService.update(req.params.id, req.body);
      res.json(user);
    } catch (error) {
      next(error);
    }
  },
  delete: async (req, res, next) => {
    try {
      const user = await userService.delete(req.params.id);
      res.json(user);
    } catch (error) {
      next(error);
    }
  },
};

Создание маршрутов API

Далее создадим маршруты API для контроллеров . Для начала создайте user.jsфайл в routesпапке и добавьте приведенный ниже фрагмент кода.

const express = require("express");
const router = express.Router();
const userController = require("../controller/userController");

/* GET users listing. */
router.route("/").get(userController.getAll).post(userController.create);
router
  .route("/:id")
  .get(userController.getById)
  .put(userController.update)
  .delete(userController.delete);

module.exports = router;

В приведенном выше фрагменте кода мы импортировали userControllerи создали экспресс-маршрутизатор. Используя экспресс-маршрутизатор, мы определяем обработчики маршрутов для контроллеров.

Теперь создайте еще один файл с именем blog.jsв папке маршрутов, чтобы определить обработчики маршрутов для контроллера блога с помощью приведенного ниже фрагмента кода.

const express = require("express");
const router = express.Router();
const blogController = require("../controller/blogController");

/* GET home page. */
router.route("/").get(blogController.getAll).post(blogController.create);
router
  .route("/:id")
  .get(blogController.getById)
  .put(blogController.update)
  .delete(blogController.delete);

module.exports = router;

Наконец, импортируйте маршруты в файл app.js и создайте промежуточное ПО для обоих маршрутов с помощью приведенного ниже фрагмента кода.

...
const userRouter = require("./routes/users");
const blogRouter = require("./routes/blog"); 

...
app.use('/users', userRouter);
app.use('/blog', blogRouter);\

...

Тестирование API

Теперь давайте проверим проект, чтобы убедиться, что все работает как положено. Сначала запустите свой сервер с помощью приведенной ниже команды.

npm start

Затем запустите Postman или любой инструмент тестирования API по вашему выбору.

Конечная точка пользователя

Отправьте запрос POST на конечную точку localhost:3000/usersс приведенными ниже полезными данными, чтобы создать пользователя.

{
  "name":"name",
  "email":"name@gmail.com",
  "password":"1234",
  "bio":"I am a software dev."
}

Тестирование конечной точки пользователя — результаты

Затем отправьте запрос GET на ту же конечную точку, чтобы получить всех зарегистрированных пользователей. Идите вперед и протестируйте конечные точки других пользователей.

Получение всех зарегистрированных пользователей - результаты

Конечная точка блога

Теперь отправьте запрос POST на конечную точку localhost:3000/blogс полезной нагрузкой ниже, чтобы создать блог для пользователя с идентификатором 1, обозначенным полем автора .

{
    "title":"My First Blog",
    "content":"Blah Blah Blah",
    "image":"Image URL",
    "author":"1"
}

Тестирование конечной точки блога — запрос POST

Затем отправьте запрос GET на ту же конечную точку, чтобы получить все блоги.

Тестирование конечной точки блога — запрос GET

Просмотр пользовательских данных с помощью Arctype

Теперь мы успешно создали наше приложение Blog. Теперь давайте посмотрим на данные пользователей с помощью Arctype. Для начала запустите Arctype, перейдите на Postgresвкладку и введите следующие Postgresучетные данные, как показано на скриншоте ниже (все то же самое, что мы делали с MySQL в начале):

Вы должны увидеть таблицу user , blog и таблицы миграции knex, в которых хранятся записи о миграциях, выполненных в приложении. Теперь нажмите на таблицу блогов, чтобы отобразить блоги пользователя, как показано на снимке экрана ниже:

Данные PostgreSQL в Arctype

Вывод

Создав демонстрационный проект, мы узнали, как создавать конечные точки REST с помощью Knex и PostgreSQL. Мы начали с того, что представили PostgreSQL и Knex и рассказали, почему вы должны их использовать, а затем создали проект блога для демонстрации. Теперь, когда вы получили необходимые знания, как бы вы использовали построитель запросов в своем следующем проекте? Подумайте о том, чтобы узнать больше о Knex на их официальном сайте и пойти еще дальше!

Ссылка: https://arctype.com/blog/postgresql-rest-api-knex/

#restapi #api #postgresql #knex

Как создавать конечные точки REST с помощью Knex и PostgreSQL
Hoang  Kim

Hoang Kim

1660278544

Cách Xây Dựng điểm Cuối REST Với Knex & PostgreSQL

Trong blog này, chúng tôi sẽ cho bạn biết cách bạn nên xây dựng các dịch vụ dựa trên REST bằng cách sử dụng Knex và PostgreSQL.

Knex và PostgreSQL là gì?

Knex là một trình tạo truy vấn SQL linh hoạt, di động và thú vị cho PostgreSQL, CockroachDB, MSSQL, MySQL, MariaDB, SQLite3, Better-SQLite3, Oracle và Amazon Redshift, trong khi PostgreSQL là một hệ thống quản lý cơ sở dữ liệu quan hệ đối tượng mã nguồn mở với mức độ linh hoạt cao. Nó có khả năng xử lý một loạt các trường hợp sử dụng, bao gồm các máy đơn lẻ, kho dữ liệu và các dịch vụ web với nhiều người dùng đồng thời. Nó là một hệ thống quản lý cơ sở dữ liệu quan hệ sử dụng và mở rộng SQL (do đó có tên), và nó có thể mở rộng rộng rãi cho nhiều trường hợp sử dụng khác nhau ngoài dữ liệu giao dịch.

PostgreSQL lưu trữ thông tin trong các bảng (được gọi là quan hệ) chứa các bộ giá trị đại diện cho các thực thể (như tài liệu và con người) và các mối quan hệ (chẳng hạn như quyền tác giả). Các thuộc tính kiểu cố định đại diện cho các thuộc tính thực thể (chẳng hạn như tiêu đề), cũng như khóa chính, được bao gồm trong các mối quan hệ. Các kiểu thuộc tính có thể là nguyên tử (ví dụ: số nguyên, dấu phẩy động hoặc boolean) hoặc có cấu trúc (chẳng hạn như một mảng, JSON lồng nhau hoặc một thủ tục).

Tại sao sử dụng Knex?

Hầu hết các nhà phát triển sử dụng Knex làm trình tạo truy vấn của họ vì những lý do sau.

  • Nó cho phép họ tạo các truy vấn giống như họ đang viết mã Javascript, trong khi nó xử lý bản dịch sang SQL.
  • Nó có hỗ trợ cho các hệ thống quản lý cơ sở dữ liệu như PostgreSQL, MySQL, SQLite và Oracle.
  • Nó hỗ trợ cả lệnh gọi lại kiểu nút truyền thống và giao diện hứa hẹn để kiểm soát luồng không đồng bộ rõ ràng hơn, cũng như giao diện luồng.
  • Nó là trình xây dựng lược đồ và truy vấn đầy đủ tính năng, hỗ trợ giao dịch (với các điểm lưu), tổng hợp kết nối và các phản hồi tiêu chuẩn hóa giữa các máy khách truy vấn và phương ngữ.

Điều kiện tiên quyết

Vì đây là hướng dẫn trình diễn thực hành, nên để bắt đầu, hãy đảm bảo hệ thống của bạn đáp ứng các yêu cầu sau:

  • Bạn đã cài đặt Node.js phiên bản 14 trở lên
  • Bạn đã cài đặt và thiết lập Arctype
  • Bạn đã thiết lập cơ sở dữ liệu PostgreSQL
  • Cài đặt Knex CLI (lệnh để làm như vậy npm i -g knex)

Với các yêu cầu trên được đáp ứng, hãy tạo một cơ sở dữ liệu mới bằng Arctype. Để bắt đầu, hãy khởi chạy ứng dụng Arctype , sau đó chọn cơ sở dữ liệu bạn muốn làm việc với:

Chọn DBMS trong Arctype

Sau đó, cung cấp thông tin xác thực của cơ sở dữ liệu được đề cập. Tất cả đều thực sự đơn giản để làm, không phức tạp ở đây!

Xác định thông tin đăng nhập cơ sở dữ liệu

Nếu bạn đã thiết lập cơ sở dữ liệu, bạn luôn có thể tạo một cơ sở dữ liệu mới bằng cách thêm một nguồn dữ liệu mới:

Thêm nguồn dữ liệu mới trong Arctype

Sau khi hoàn tất, bạn sẽ thấy các bảng bên dưới cơ sở dữ liệu của mình ở phía bên trái trong Arctype.

Tạo máy chủ Node.js

Bây giờ, hãy tạo một thư mục mới cho dự án của bạn và khởi tạo một dự án mới bằng các lệnh bên dưới.

mkdir knex-demo && cd knex-demo
npm init -y

Sau đó, cài đặt các gói cần thiết bằng cách chạy lệnh sau:

npm install pg express knex

Với lệnh trên, bạn đã cài đặt mô-đun PostgreSQL Node.js expressknexmô-đun.

Bây giờ, hãy tạo cấu trúc thư mục sau đây trong thư mục quỳ-demo.

📦knex-demo
┣ 📂src
┃ ┣ 📂config
┃ ┣ 📂controller
┃ ┣ 📂routes
┃ ┣ 📂service
┃ ┗ 📜app.js
┣ 📜package-lock.json
┗ 📜package.json

Sau đó, trong app.jstệp, hãy tạo một máy chủ Node.js Express với đoạn mã bên dưới.

const express = require("express");   

const app = express();

app.use(express.json());

app.listen(3000, () => {
  console.log("Server is running on port 3000");
});

Cuối cùng, sửa đổi package.jsontệp để thêm lệnh script.

 "scripts": {
    "start": "node src/app.js"
  },

Thiết lập Knex

Khi bạn đã tạo cơ sở dữ liệu, hãy thiết lập Knex và kết nối với cơ sở dữ liệu. Để bắt đầu, hãy chạy lệnh dưới đây trên thiết bị đầu cuối của bạn để khởi tạo xương bánh chè.

knex init

Lệnh trên sẽ tạo một knexfile.jstệp trong thư mục gốc dự án của bạn với các đoạn mã để kết nối cơ sở dữ liệu của bạn với các môi trường khác nhau (phát triển, dàn dựng, sản xuất.) Theo mặc định, nó sử dụng cơ sở dữ liệu SQLite trong môi trường phát triển, bạn sẽ cần sửa đổi mã để sử dụng cơ sở dữ liệu Postgres của bạn.

// Update with your config settings.

/**
 * @type { Object.<string, import("knex").Knex.Config> }
 */
module.exports = {
  development: {
    client: "postgresql",
    connection: {
      database: "blogs",
      user: "postgres",
      password: "1234",
    },
  },

  staging: {
    client: "postgresql",
    connection: {
      database: "<Your Staging DB>",
      user: "username",
      password: "password",
    },
    pool: {
      min: 2,
      max: 10,
    },
    migrations: {
      tableName: "knex_migrations",
    },
  },

  production: {
    client: "postgresql",
    connection: {
      database: "<Your Production DB>",
      user: "username",
      password: "password",
    },
    pool: {
      min: 2,
      max: 10,
    },
    migrations: {
      tableName: "knex_migrations",
    },
  },
};

Tệp của bạn knexfile.jssẽ giống như đoạn mã ở trên. Bạn có thể sửa đổi mã để đáp ứng bất kỳ yêu cầu dự án nào khác mà bạn có thể có.

Tạo tệp di chuyển

Bây giờ, hãy chạy lệnh bên dưới để tạo tệp di chuyển của bạn cho bảng của người dùng và xác định bảng sẽ trông như thế nào bằng cách chạy lệnh bên dưới.

knex migrate:make users

Lệnh trên sẽ tạo một migrations/timestamp_userstệp trong thư mục gốc của dự án của bạn. Bây giờ chúng ta hãy xác định lược đồ trong các hàm lên và xuống.

/**
 * @param { import("knex").Knex } knex
 * @returns { Promise<void> }
 */
exports.up = function (knex) {
  return knex.schema.createTable("users", (table) => {
    table.increments("id").primary();
    table.string("name").notNullable();
    table.string("email").notNullable();
    table.string("password").notNullable();
    table.string("avatar").defaultTo("https://i.imgur.com/Xq2bZCY.png");
    table.string("bio").defaultTo("I am a new user");
    table.timestamp("created_at").defaultTo(knex.fn.now());
    table.timestamp("updated_at").defaultTo(knex.fn.now());
  });
};

/**
 * @param { import("knex").Knex } knex
 * @returns { Promise<void> }
 */
exports.down = function (knex) {
  return knex.schema.dropTable("users");
};

Mã trong migrations/timestamp_users.jstệp phải giống như đoạn mã trên. Chúng tôi đã xác định lược đồ của người dùng. Trường đầu tiên là một idtrường có tự động gia tăng được đặt thành true và một ràng buộc duy nhất, sau đó chúng ta có các trường chúng ta cần cho bảng của người dùng.

Sau đó, trong downhàm, chúng tôi sẽ loại bỏ bất kỳ bảng hiện có nào có tên người dùng trước khi chúng tôi tạo bảng mới của mình.

Để tạo bảng này trong cơ sở dữ liệu của bạn, bạn cần chạy lại lệnh di chuyển, lần này bạn cần thêm latestcờ để chỉ xác nhận các thay đổi mới trong tệp.

knex migrate:latest

Tiếp theo, tạo lược đồ blog bằng cách chạy lệnh di chuyển bên dưới trên thiết bị đầu cuối của bạn.

knex migrate:make blogs

Sau đó, thêm đoạn mã bên dưới vào hàm up để xác định lược đồ của blog.

/**
 * @param { import("knex").Knex } knex
 * @returns { Promise<void> }
 */
exports.up = function (knex) {
  return knex.schema.createTable("blog", (table) => {
    table.increments("id").primary();
    table.string("title").notNullable();
    table.string("content").notNullable();
    table.string("image").notNullable();
    table.timestamp("created_at").defaultTo(knex.fn.now());
    table.timestamp("updated_at").defaultTo(knex.fn.now());
  });
};

/**
 * @param { import("knex").Knex } knex
 * @returns { Promise<void> }
 */
exports.down = function (knex) {
    return knex.schema.dropTable("blog");
};

Trong đoạn mã trên, chúng tôi đã tạo một lược đồ blog và xác định các trường chúng tôi cần trong bảng blog. Chúng tôi cũng đang loại bỏ bất kỳ bảng nào hiện có với các blog tên .

Tạo mối quan hệ bảng

Bây giờ hãy tạo mối quan hệ giữa lược đồ của người dùng và lược đồ của blog. Bằng cách này, chúng tôi có thể liên kết blog với những người dùng tạo ra chúng. Để làm điều đó, chúng tôi cần cập nhật mã trong timestamps_blogs.jstệp với mã sau:

/**
 * @param { import("knex").Knex } knex
 * @returns { Promise<void> }
 */
exports.up = function (knex) {
  return knex.schema.createTable("blog", (table) => {
    table.increments("id").primary();
    table.string("title").notNullable();
    table.string("content").notNullable();
    table.string("image").notNullable();
    table
      .integer("author")
      .unsigned()
      .references("id")
      .inTable("users")
      .onDelete("CASCADE");
    table.timestamp("created_at").defaultTo(knex.fn.now());
    table.timestamp("updated_at").defaultTo(knex.fn.now());
  });
};

/**
 * @param { import("knex").Knex } knex
 * @returns { Promise<void> }
 */
exports.down = function (knex) {
    return knex.schema.dropTable("blog");
};

Trong đoạn mã trên, chúng tôi đã sửa đổi trường tác giả để tham chiếu id của từng người dùng trong lược đồ của người dùng. Di OnDeletechúc đảm bảo blog sẽ bị xóa khi tài khoản của người dùng bị xóa.

Tiếp theo, tạo một db.jstệp trong thư mục cấu hình và thêm đoạn mã bên dưới.

const knex = require("knex");
const config = require("../../knexfile");
module.exports = knex(config.development);

Trong đoạn mã trên, chúng tôi đang nhập configtừ knexfilevà khởi tạo đối tượng quỳ, vì vậy kể từ khi chạy ứng dụng trên môi trường phát triển, chúng tôi sẽ gọi developmentđối tượng cấu hình.

Tạo dịch vụ

Với các bảng cơ sở dữ liệu của chúng ta đã tạo, hãy tạo một dịch vụ thực hiện các hoạt động CRUD trong các bảng cơ sở dữ liệu. Tạo một userService.jstệp trong servicethư mục và thêm đoạn mã được chỉ định bên dưới.

const db = require('../config/db');

module.exports = userService = {
  getAll: async () => {
    const users = await db("users");
    return users;
  },
  getById: async (id) => {
    const user = await db("users").where("id", id);
    return user;
  },
  create: async (user) => {
    const users = await db("users").insert(user);
    return users;
  },
  update: async (id, user) => {
    const users = await db("users").where("id", id).update({
      name: user.name,
      email: user.email,
      password: user.password,
      avatar: user.avatar,
      bio: user.bio,
    });
    return users;
  },
  delete: async (id) => {
    const users = await db("users").where("id", id).del();
    return users;
  },
};

Trong đoạn mã trên, chúng tôi đã nhập cấu hình quỳ. Sau đó, chúng tôi tạo userServiceđối tượng và tạo các phương thức cho các hoạt động CRUD.

Tiếp theo, tạo một blogService.jstệp trong thư mục dịch vụ và thêm đoạn mã bên dưới.

const db = require("../config/db");

module.exports = blogService = {
  getAll: async () => {
    const blogs = await db("blog")
      .join("users", "users.id", "blog.author")
      .select(
        "blog.*",
        "users.name",
        "users.avatar",
        "users.bio",
        "users.email"
      );
    return blogs;
  },
  getById: async (id) => {
    console.log(id);
    const blog = await db("blog").where({ id });
    return blog;
  },
  create: async (blog) => {
    const blogs = await db("blog").insert(blog);
    return blogs;
  },
  update: async (id, blog) => {
    const blogs = await db("blog").where("id", id).update({
      title: blog.title,
      content: blog.content,
      image: blog.image,
    });
    return blogs;
  },
  delete: async (id) => {
    const blogs = await db("blogs").where("id", id).del();
    return blogs;
  },
};

Trong đoạn mã trên, chúng tôi đã tạo các hoạt động CRUD cho blogService của dịch vụ. Trong getAllphương pháp chúng ta đang tham gia usersbảng với blogsbảng, sử dụng phương pháp chọn cho selectcác trường chúng ta muốn hiển thị cho người dùng - nếu bây giờ chúng ta gọi dịch vụ, chúng ta có thể lấy các blog và người dùng đã đăng chúng.

Tạo bộ điều khiển

Bây giờ chúng ta hãy tạo bộ điều khiển để sử dụng dịch vụ mà chúng ta vừa tạo. Hãy bắt đầu với bộ điều khiển của người dùng. Vì vậy, hãy tạo một userController.jstệp trong thư mục bộ điều khiển và thêm đoạn mã bên dưới.

const userService = require("../service/userService");
module.exports = userController = {
  getAll: async (req, res, next) => {
    try {
      const users = await userService.getAll();
      res.json(users);
    } catch (error) {
      next(error);
    }
  },
  getById: async (req, res, next) => {
    try {
      const user = await userService.getById(req.params.id);
      res.json(user);
    } catch (error) {
      next(error);
    }
  },
  create: async (req, res, next) => {
    try {
      const user = await userService.create(req.body);
      res.json(user);
    } catch (error) {
      next(error);
    }
  },
  update: async (req, res, next) => {
    try {
      const user = await userService.update(req.params.id, req.body);
      res.json(user);
    } catch (error) {
      next(error);
    }
  },
  delete: async (req, res, next) => {
    try {
      const user = await userService.delete(req.params.id);
      res.json(user);
    } catch (error) {
      next(error);
    }
  },
};

Bây giờ, hãy tạo một blogController.jstệp trong thư mục bộ điều khiểnblogService để sử dụng với đoạn mã bên dưới.

const userService = require("../service/userService");
module.exports = userController = {
  getAll: async (req, res, next) => {
    try {
      const users = await userService.getAll();
      res.json(users);
    } catch (error) {
      next(error);
    }
  },
  getById: async (req, res, next) => {
    try {
      const user = await userService.getById(req.params.id);
      res.json(user);
    } catch (error) {
      next(error);
    }
  },
  create: async (req, res, next) => {
    try {
      const user = await userService.create(req.body);
      res.json(user);
    } catch (error) {
      next(error);
    }
  },
  update: async (req, res, next) => {
    try {
      const user = await userService.update(req.params.id, req.body);
      res.json(user);
    } catch (error) {
      next(error);
    }
  },
  delete: async (req, res, next) => {
    try {
      const user = await userService.delete(req.params.id);
      res.json(user);
    } catch (error) {
      next(error);
    }
  },
};

Tạo các tuyến API

Tiếp theo, hãy tạo các tuyến API cho các bộ điều khiển . Để bắt đầu, hãy tạo một user.jstệp trong routesthư mục và thêm đoạn mã bên dưới.

const express = require("express");
const router = express.Router();
const userController = require("../controller/userController");

/* GET users listing. */
router.route("/").get(userController.getAll).post(userController.create);
router
  .route("/:id")
  .get(userController.getById)
  .put(userController.update)
  .delete(userController.delete);

module.exports = router;

Trong đoạn mã trên, chúng tôi đã nhập userControllervà tạo một bộ định tuyến express. Sử dụng bộ định tuyến express, chúng tôi xác định các trình xử lý tuyến đường cho các bộ điều khiển.

Bây giờ, hãy tạo một tệp khác được gọi blog.jstrong thư mục định tuyến để xác định trình xử lý tuyến đường cho trình điều khiển blog bằng đoạn mã bên dưới.

const express = require("express");
const router = express.Router();
const blogController = require("../controller/blogController");

/* GET home page. */
router.route("/").get(blogController.getAll).post(blogController.create);
router
  .route("/:id")
  .get(blogController.getById)
  .put(blogController.update)
  .delete(blogController.delete);

module.exports = router;

Cuối cùng, nhập các tuyến trong tệp app.js và tạo phần mềm trung gian cho cả hai tuyến bằng đoạn mã bên dưới.

...
const userRouter = require("./routes/users");
const blogRouter = require("./routes/blog"); 

...
app.use('/users', userRouter);
app.use('/blog', blogRouter);\

...

Kiểm tra API

Bây giờ chúng ta hãy kiểm tra dự án để đảm bảo mọi thứ hoạt động như mong đợi. Đầu tiên, khởi động máy chủ y0ur bằng lệnh bên dưới.

npm start

Sau đó khởi chạy Postman hoặc bất kỳ công cụ kiểm tra API nào bạn chọn.

Điểm cuối người dùng

Gửi yêu cầu ĐĂNG tới điểm cuối localhost:3000/usersvới tải trọng bên dưới để tạo người dùng.

{
  "name":"name",
  "email":"name@gmail.com",
  "password":"1234",
  "bio":"I am a software dev."
}

Kiểm tra Điểm cuối của Người dùng - Kết quả

Tiếp theo, gửi yêu cầu GET đến cùng một điểm cuối để nhận được tất cả người dùng đã đăng ký. Hãy tiếp tục và kiểm tra các điểm cuối của người dùng khác.

Nhận tất cả người dùng đã đăng ký - Kết quả

Điểm cuối của Blog

Bây giờ hãy gửi một yêu cầu ĐĂNG đến điểm cuối localhost:3000/blogvới tải trọng bên dưới để tạo blog cho người dùng có id là 1 được ký hiệu bởi trường tác giả .

{
    "title":"My First Blog",
    "content":"Blah Blah Blah",
    "image":"Image URL",
    "author":"1"
}

Kiểm tra Điểm cuối của Blog - Yêu cầu ĐĂNG

Sau đó, gửi một yêu cầu GET đến cùng một điểm cuối để nhận tất cả các blog.

Kiểm tra Điểm cuối của Blog - NHẬN Yêu cầu

Xem dữ liệu người dùng với Arctype

Bây giờ chúng tôi đã tạo thành công ứng dụng Blog của mình. Bây giờ, hãy xem xét dữ liệu của người dùng với Arctype. Để bắt đầu, hãy khởi chạy Arctype, nhấp vào Postgrestab và nhập Postgresthông tin đăng nhập sau, như được hiển thị trong ảnh chụp màn hình bên dưới (tất cả đều giống như chúng ta đã làm với MySQL lúc bắt đầu):

Bạn sẽ thấy người dùng , bảng blog và bảng di chuyển xương bánh chè lưu giữ hồ sơ về các di chuyển được thực hiện trong ứng dụng. Bây giờ hãy nhấp vào bảng blog để hiển thị các blog của người dùng, như được hiển thị trong ảnh chụp màn hình bên dưới:

Dữ liệu PostgreSQL trong Arctype

Sự kết luận

Bằng cách xây dựng một dự án demo, chúng tôi đã học cách xây dựng các điểm cuối REST với Knex và PostgreSQL. Chúng tôi bắt đầu bằng cách giới thiệu PostgreSQL và Knex và tại sao bạn nên sử dụng chúng, sau đó chúng tôi tạo một dự án blog để trình diễn. Bây giờ bạn đã có kiến ​​thức mà bạn tìm kiếm, bạn sẽ sử dụng trình tạo truy vấn như thế nào trong dự án tiếp theo của mình? Hãy cân nhắc tìm hiểu thêm về Knex từ trang web chính thức của họ và tiến xa hơn nữa!

Liên kết: https://arctype.com/blog/postgresql-rest-api-knex/

#restapi #api #postgresql #knex

Cách Xây Dựng điểm Cuối REST Với Knex & PostgreSQL
Elian  Harber

Elian Harber

1659888840

Dcrdata: Decred Block Explorer, with Packages, App for Data Collection

dcrdata

Overview

dcrdata is an original Decred block explorer, with packages and apps for data collection, presentation, and storage. The backend and middleware are written in Go. On the front end, Webpack enables the use of modern javascript features, as well as SCSS for styling.

Release Status

Always run the Current release or on the Current stable branch. Do not use master in production.

 SeriesBranchLatest release tagdcrd RPC server version required
Development6.1masterN/A^7.0.0 (dcrd v1.7 release)
Current6.06.0-stablerelease-v6.0^6.2.0 (dcrd v1.6 release)

Repository Overview

../dcrdata                The main Go MODULE. See cmd/dcrdata for the explorer executable.
├── api/types             The exported structures used by the dcrdata and Insight APIs.
├── blockdata             Package blockdata is the primary data collection and
|                           storage hub, and chain monitor.
├── cmd
│   └── dcrdata           MODULE for the dcrdata explorer executable.
│       ├── api           dcrdata's own HTTP API
│       │   └── insight   The Insight API
│       ├── explorer      Powers the block explorer pages.
│       ├── middleware    HTTP router middleware used by the explorer
│       ├── notification  Manages dcrd notifications synchronous data collection.
│       ├── public        Public resources for block explorer (css, js, etc.)
│       └── views         HTML templates for block explorer
├── db
│   ├── cache             Package cache provides a caching layer that is used by dcrpg.
│   ├── dbtypes           Package dbtypes with common data types.
│   └── dcrpg             MODULE and package dcrpg providing PostgreSQL backend.
├── dev                   Shell scripts for maintenance and deployment.
├── docs                  Extra documentation.
├── exchanges             MODULE and package for gathering data from public exchange APIs
│   ├── rateserver        rateserver app, which runs an exchange bot for collecting
│   |                       exchange rate data, and a gRPC server for providing this
│   |                       data to multiple clients like dcrdata.
|   └── ratesproto        Package dcrrates implementing a gRPC protobuf service for
|                           communicating exchange rate data with a rateserver.
├── explorer/types        Types used primarily by the explorer pages.
├── gov                   MODULE for the on- and off-chain governance packages.
│   ├── agendas           Package agendas defines a consensus deployment/agenda DB.
│   └── politeia          Package politeia defines a Politeia proposal DB.
│       ├── piclient      Package piclient provides functions for retrieving data
|       |                   from the Politeia web API.
│       └── types         Package types provides several JSON-tagged structs for
|                           dealing with Politeia data exchange.
├── mempool               Package mempool for monitoring mempool for transactions,
|                           data collection, distribution, and storage.
├── netparams             Package netparams defines the TCP port numbers for the
|                           various networks (mainnet, testnet, simnet).
├── pubsub                Package pubsub implements a websocket-based pub-sub server
|   |                       for blockchain data.
│   ├── democlient        democlient app provides an example for using psclient to
|   |                       register for and receive messages from a pubsub server.
│   ├── psclient          Package psclient is a basic client for the pubsub server.
│   └── types             Package types defines types used by the pubsub client
|                           and server.
├── rpcutils              Package rpcutils contains helper types and functions for
|                           interacting with a chain server via RPC.
├── semver                Defines the semantic version types.
├── stakedb               Package stakedb, for tracking tickets
├── testutil
│   ├── apiload           An HTTP API load testing application
|   └── dbload            A DB load testing application
└── txhelpers             Package txhelpers provides many functions and types for
                            processing blocks, transactions, voting, etc.

Requirements

  • Go 1.17 or 1.18
  • Node.js 16.x or 17.x. Node.js is only used as a build tool, and is not used at runtime.
  • Running dcrd running with --txindex --addrindex, and synchronized to the current best block on the network. On startup, dcrdata will verify that the dcrd version is compatible.
  • PostgreSQL 11+

Docker Support

Dockerfiles are provided for convenience, but NOT SUPPORTED. See the Docker documentation for more information. The supported dcrdata build instructions are described below.

Building

The dcrdata build process comprises two general steps:

  1. Bundle the static web page assets with Webpack (via the npm tool).
  2. Build the dcrdata executable from the Go source files.

These steps are described in detail in the following sections.

NOTE: The following instructions assume a Unix-like shell (e.g. bash).

Preparation

Install Go

Verify Go installation:

go env GOROOT GOPATH

Ensure $GOPATH/bin is on your $PATH.

Clone the dcrdata repository. It is conventional to put it under GOPATH, but this is no longer necessary (or recommend) with Go modules. For example:

git clone https://github.com/decred/dcrdata $HOME/go-work/github/decred/dcrdata

Install Node.js, which is required to lint and package the static web assets.

Note that none of the above is required at runtime.

Package the Static Web Assets

Webpack, a JavaScript module bundler, is used to compile and package the static assets in the cmd/dcrdata/public folder. Node.js' npm tool is used to install the required Node.js dependencies and build the bundled JavaScript distribution for deployment.

First, install the build dependencies:

cd cmd/dcrdata
npm clean-install # creates node_modules folder fresh

Then, for production, build the webpack bundle:

npm run build # creates public/dist folder

Alternatively, for development, npm can be made to watch for and integrate JavaScript source changes:

npm run watch

See Front End Development for more information.

Building dcrdata with Go

Change to the cmd/dcrdata folder and build:

cd cmd/dcrdata
go build -v

The go tool will process the source code and automatically download dependencies. If the dependencies are configured correctly, there will be no modifications to the go.mod and go.sum files.

Note that performing the above commands with older versions of Go within $GOPATH may require setting GO111MODULE=on.

As a reward for reading this far, you may use the build.sh script to mostly automate the build steps.

Setting build version flags

By default, the version string will be postfixed with "-pre+dev". For example, dcrdata version 5.1.0-pre+dev (Go version go1.12.7). However, it may be desirable to set the "pre" and "dev" values to different strings, such as "beta" or the actual commit hash. To set these values, build with the -ldflags switch as follows:

go build -v -ldflags \
  "-X main.appPreRelease=beta -X main.appBuild=`git rev-parse --short HEAD`"

This produces a string like dcrdata version 6.0.0-beta+750fd6c2 (Go version go1.16.2).

Runtime Resources

The config file, logs, and data files are stored in the application data folder, which may be specified via the -A/--appdata and -b/--datadir settings. However, the location of the config file may also be set with -C/--configfile. The default paths for your system are shown in the --help description. If encountering errors involving file system paths, check the permissions on these folders to ensure that the user running dcrdata is able to access these paths.

The "public" and "views" folders must be in the same folder as the dcrdata executable. Set read-only permissions as appropriate.

Updating

Update the repository (assuming you have master checked out in GOPATH):

cd $HOME/go-work/github/decred/dcrdata
git pull origin master

Look carefully for errors with git pull, and reset locally modified files if necessary.

Next, build dcrdata and bundle the web assets:

cd cmd/dcrdata
go build -v
npm clean-install
npm run build # or npm run watch

Note that performing the above commands with versions of Go prior to 1.16 within $GOPATH may require setting GO111MODULE=on.

Upgrading Instructions

From v3.x or later

No special actions are required. Simply start the new dcrdata and automatic database schema upgrades and table data patches will begin.

From v2.x or earlier

The database scheme change from dcrdata v2.x to v3.x does not permit an automatic migration. The tables must be rebuilt from scratch:

Drop the old dcrdata database, and create a new empty dcrdata database.

-- Drop the old database.
DROP DATABASE dcrdata;

-- Create a new database with the same "pguser" set in the dcrdata.conf.
CREATE DATABASE dcrdata OWNER dcrdata;

Delete the dcrdata data folder (i.e. corresponding to the datadir setting). By default, datadir is in {appdata}/data:

  • Linux: ~/.dcrdata/data
  • Mac: ~/Library/Application Support/Dcrdata/data
  • Windows: C:\Users\<your-username>\AppData\Local\Dcrdata\data (%localappdata%\Dcrdata\data)

With dcrd synchronized to the network's best block, start dcrdata to begin the initial block data sync.

Getting Started

Configuring PostgreSQL (IMPORTANT! Seriously, read this.)

It is crucial that you configure your PostgreSQL server for your hardware and the dcrdata workload.

Read postgresql-tuning.conf carefully for details on how to make the necessary changes to your system. A helpful online tool for determining good settings for your system is called PGTune. Note that when using this tool to subtract 1.5-2GB from your system RAM so dcrdata itself will have plenty of memory. DO NOT simply use this file in place of your existing postgresql.conf. DO NOT simply copy and paste these settings into the existing postgresql.conf. It is necessary to edit the existing postgresql.conf, reviewing all the settings to ensure the same configuration parameters are not set in two different places in the file (postgres will not complain).

If you tune PostgreSQL to fully utilize remaining RAM, you are limiting the RAM available to the dcrdata process, which will increase as request volume increases and its cache becomes fully utilized. Allocate sufficient memory to dcrdata for your application, and use a reverse proxy such as nginx with cache locking features to prevent simultaneous requests to the same resource.

On Linux, you may wish to use a unix domain socket instead of a TCP connection. The path to the socket depends on the system, but it is commonly /var/run/postgresql. Just set this path in pghost.

Creating the dcrdata Configuration File

Begin with the sample configuration file. With the default appdata directory for the current user on Linux:

cp sample-dcrdata.conf ~/.dcrdata/dcrdata.conf

Then edit dcrdata.conf with your dcrd RPC settings. See the output of dcrdata --help for a list of all options and their default values.

Indexing the Blockchain

If dcrdata has not previously been run with the PostgreSQL database backend, it is necessary to perform a bulk import of blockchain data and generate table indexes. This will be done automatically by dcrdata on a fresh startup. Do NOT interrupt the initial sync or use the browser interface until it is completed.

Note that dcrdata requires that dcrd is running with some optional indexes enabled. By default, these indexes are not turned on when dcrd is installed. To enable them, set the following in dcrd.conf:

txindex=1
addrindex=1

If these parameters are not set, dcrdata will be unable to retrieve transaction details and perform address searches, and will exit with an error mentioning these indexes.

Starting dcrdata

Launch the dcrdata daemon and allow the databases to process new blocks. Concurrent synchronization of both stake and PostgreSQL databases is performed, typically requiring between 1.5 to 8 hours. See System Hardware Requirements for more information. Please reread Configuring PostgreSQL (IMPORTANT! Seriously, read this.) of you have performance issues.

On subsequent launches, only blocks new to dcrdata are processed.

./dcrdata    # don't forget to configure dcrdata.conf in the appdata folder!

Do NOT interrupt the initial sync or use the browser interface until it is completed. Follow the messages carefully, and if you are uncertain of the current sync status, check system resource utilization. Interrupting the initial sync can leave dcrdata and it's databases in an unrecoverable or suboptimal state. The main steps of the initial sync process are:

  1. Initial block data import
  2. Indexing
  3. Spending transaction relationship updates
  4. Final DB analysis and indexing
  5. Catch-up to network in normal sync mode
  6. Populate charts historical data
  7. Update Pi repo and parse proposal records (git will be running)
  8. Final catch-up and UTXO cache pre-warming
  9. Update project fund data and then idle

Unlike dcrdata.conf, which must be placed in the appdata folder or explicitly set with -C, the "public" and "views" folders must be in the same folder as the dcrdata executable.

System Hardware Requirements

The time required to sync varies greatly with system hardware and software configuration. The most important factor is the storage medium on the database machine. An SSD (preferably NVMe, not SATA) is REQUIRED. The PostgreSQL operations are extremely disk intensive, especially during the initial synchronization process. Both high throughput and low latencies for fast random accesses are essential.

dcrdata only (PostgreSQL on other host)

Without PostgreSQL, the dcrdata process can get by with:

  • 1 CPU core
  • 2 GB RAM
  • HDD with 8GB free space

dcrdata and PostgreSQL on same host

These specifications assume dcrdata and postgres are running on the same machine.

Minimum:

  • 2 CPU core
  • 6 GB RAM
  • SSD with 120GB free space (no spinning hard drive for the DB!)

Recommend:

  • 3+ CPU cores
  • 12+ GB RAM
  • NVMe SSD with 120 GB free space

dcrdata Daemon

The cmd/dcrdata folder contains the main package for the dcrdata app, which has several components including:

  1. Block explorer (web interface).
  2. Blockchain monitoring and data collection.
  3. Mempool monitoring and reporting.
  4. Database backend interfaces.
  5. RESTful JSON API (custom and Insight) over HTTP(S).
  6. Websocket-based pub-sub server.
  7. Exchange rate bot and gRPC server.

Block Explorer

After dcrdata syncs with the blockchain server via RPC, by default it will begin listening for HTTP connections on http://127.0.0.1:7777/. This means it starts a web server listening on IPv4 localhost, port 7777. Both the interface and port are configurable. The block explorer and the JSON APIs are both provided by the server on this port.

Note that while dcrdata can be started with HTTPS support, it is recommended to employ a reverse proxy such as Nginx ("engine x"). See sample-nginx.conf for an example Nginx configuration.

APIs

The dcrdata block explorer is exposed by two APIs: a Decred implementation of the Insight API, and its own JSON HTTP API. The Insight API uses the path prefix /insight/api. The dcrdata API uses the path prefix /api. File downloads are served from the /download path.

Insight API

The Insight API is accessible via HTTP via REST or WebSocket.

See the Insight API documentation for further details.

dcrdata API

The dcrdata API is a REST API accessible via HTTP. To call the dcrdata API, use the /api path prefix.

Endpoint List

Best blockPathType
Summary/block/best?txtotals=[true|false]types.BlockDataBasic
Stake info/block/best/postypes.StakeInfoExtended
Header/block/best/headerdcrjson.GetBlockHeaderVerboseResult
Raw Header (hex)/block/best/header/rawstring
Hash/block/best/hashstring
Height/block/best/heightint
Raw Block (hex)/block/best/rawstring
Size/block/best/sizeint32
Subsidy/block/best/subsidytypes.BlockSubsidies
Transactions/block/best/txtypes.BlockTransactions
Transactions Count/block/best/tx/counttypes.BlockTransactionCounts
Verbose block result/block/best/verbosedcrjson.GetBlockVerboseResult
Block X (block index)PathType
Summary/block/Xtypes.BlockDataBasic
Stake info/block/X/postypes.StakeInfoExtended
Header/block/X/headerdcrjson.GetBlockHeaderVerboseResult
Raw Header (hex)/block/X/header/rawstring
Hash/block/X/hashstring
Raw Block (hex)/block/X/rawstring
Size/block/X/sizeint32
Subsidy/block/best/subsidytypes.BlockSubsidies
Transactions/block/X/txtypes.BlockTransactions
Transactions Count/block/X/tx/counttypes.BlockTransactionCounts
Verbose block result/block/X/verbosedcrjson.GetBlockVerboseResult
Block H (block hash)PathType
Summary/block/hash/Htypes.BlockDataBasic
Stake info/block/hash/H/postypes.StakeInfoExtended
Header/block/hash/H/headerdcrjson.GetBlockHeaderVerboseResult
Raw Header (hex)/block/hash/H/header/rawstring
Height/block/hash/H/heightint
Raw Block (hex)/block/hash/H/rawstring
Size/block/hash/H/sizeint32
Subsidy/block/best/subsidytypes.BlockSubsidies
Transactions/block/hash/H/txtypes.BlockTransactions
Transactions count/block/hash/H/tx/counttypes.BlockTransactionCounts
Verbose block result/block/hash/H/verbosedcrjson.GetBlockVerboseResult
Block range (X < Y)PathType
Summary array for blocks on [X,Y]/block/range/X/Y[]types.BlockDataBasic
Summary array with block index step S/block/range/X/Y/S[]types.BlockDataBasic
Size (bytes) array/block/range/X/Y/size[]int32
Size array with step S/block/range/X/Y/S/size[]int32
Transaction T (transaction id)PathType
Transaction details/tx/T?spends=[true|false]types.Tx
Transaction details w/o block info/tx/trimmed/Ttypes.TrimmedTx
Inputs/tx/T/in[]types.TxIn
Details for input at index X/tx/T/in/Xtypes.TxIn
Outputs/tx/T/out[]types.TxOut
Details for output at index X/tx/T/out/Xtypes.TxOut
Vote info (ssgen transactions only)/tx/T/vinfotypes.VoteInfo
Ticket info (sstx transactions only)/tx/T/tinfotypes.TicketInfo
Serialized bytes of the transaction/tx/hex/Tstring
Same as /tx/trimmed/T/tx/decoded/Ttypes.TrimmedTx
Transactions (batch)PathType
Transaction details (POST body is JSON of types.Txns)/txs?spends=[true|false][]types.Tx
Transaction details w/o block info/txs/trimmed[]types.TrimmedTx
Address APathType
Summary of last 10 transactions/address/Atypes.Address
Number and value of spent and unspent outputs/address/A/totalstypes.AddressTotals
Verbose transaction result for last 
10 transactions
/address/A/rawtypes.AddressTxRaw
Summary of last N transactions/address/A/count/Ntypes.Address
Verbose transaction result for last 
N transactions
/address/A/count/N/rawtypes.AddressTxRaw
Summary of last N transactions, skipping M/address/A/count/N/skip/Mtypes.Address
Verbose transaction result for last 
N transactions, skipping M
/address/A/count/N/skip/M/rawtypes.AddressTxRaw
Transaction inputs and outputs as a CSV formatted file./download/address/io/ACSV file
Stake Difficulty (Ticket Price)PathType
Current sdiff and estimates/stake/difftypes.StakeDiff
Sdiff for block X/stake/diff/b/X[]float64
Sdiff for block range [X,Y] (X <= Y)/stake/diff/r/X/Y[]float64
Current sdiff separately/stake/diff/currentdcrjson.GetStakeDifficultyResult
Estimates separately/stake/diff/estimatesdcrjson.EstimateStakeDiffResult
Ticket PoolPathType
Current pool info (size, total value, and average price)/stake/pooltypes.TicketPoolInfo
Current ticket pool, in a JSON object with a "tickets" key holding an array of ticket hashes/stake/pool/full[]string
Pool info for block X/stake/pool/b/Xtypes.TicketPoolInfo
Full ticket pool at block height or hash H/stake/pool/b/H/full[]string
Pool info for block range [X,Y] (X <= Y)/stake/pool/r/X/Y?arrays=[true|false]*[]apitypes.TicketPoolInfo

The full ticket pool endpoints accept the URL query ?sort=[true|false] for requesting the tickets array in lexicographical order. If a sorted list or list with deterministic order is not required, using sort=false will reduce server load and latency. However, be aware that the ticket order will be random, and will change each time the tickets are requested.

*For the pool info block range endpoint that accepts the arrays url query, a value of true will put all pool values and pool sizes into separate arrays, rather than having a single array of pool info JSON objects. This may make parsing more efficient for the client.

Votes and Agendas InfoPathType
The current agenda and its status/stake/vote/infodcrjson.GetVoteInfoResult
All agendas high level details/agendas[]types.AgendasInfo
Details for agenda {agendaid}/agendas/{agendaid}types.AgendaAPIResponse
MempoolPathType
Ticket fee rate summary/mempool/sstxapitypes.MempoolTicketFeeInfo
Ticket fee rate list (all)/mempool/sstx/feesapitypes.MempoolTicketFees
Ticket fee rate list (N highest)/mempool/sstx/fees/Napitypes.MempoolTicketFees
Detailed ticket list (fee, hash, size, age, etc.)/mempool/sstx/detailsapitypes.MempoolTicketDetails
Detailed ticket list (N highest fee rates)/mempool/sstx/details/Napitypes.MempoolTicketDetails
ExchangesPathType
Exchange data summary/exchangesexchanges.ExchangeBotState
List of available currency codes/exchanges/codes[]string

Exchange monitoring is off by default. Server must be started with --exchange-monitor to enable exchange data. The server will set a default currency code. To use a different code, pass URL parameter ?code=[code]. For example, /exchanges?code=EUR.

OtherPathType
Status/statustypes.Status
Health (HTTP 200 or 503)/status/happytypes.Happy
Coin Supply/supplytypes.CoinSupply
Coin Supply Circulating (Mined)/supply/circulating?dcr=[true|false]int (default) or float (dcr=true)
Endpoint list (always indented)/list[]string

All JSON endpoints accept the URL query indent=[true|false]. For example, /stake/diff?indent=true. By default, indentation is off. The characters to use for indentation may be specified with the indentjson string configuration option.

Important Note About Mempool

Although there is mempool data collection and serving, it is very important to keep in mind that the mempool in your node (dcrd) is not likely to be exactly the same as other nodes' mempool. Also, your mempool is cleared out when you shutdown dcrd. So, if you have recently (e.g. after the start of the current ticket price window) started dcrd, your mempool will be missing transactions that other nodes have.

Front End Development

Make sure you have a recent version of node and npm installed.

From the cmd/dcrdata directory, run the following command to install the node modules.

npm clean-install

This will create and install into a directory named node_modules.

You'll also want to run npm clean-install after merging changes from upstream. It is run for you when you use the build script (./dev/build.sh).

For development, there's a webpack script that watches for file changes and automatically bundles. To use it, run the following command in a separate terminal and leave it running while you work. You'll only use this command if you are editing javascript files.

npm run watch

For production, bundle assets via:

npm run build

You will need to at least build if changes have been made. watch essentially runs build after file changes, but also performs some additional checks.

CSS Guidelines

Webpack compiles SCSS to CSS while bundling. The watch script described above also watches for changes in these files and performs linting to ensure syntax compliance.

Before you write any CSS, see if you can achieve your goal by using existing classes available in Bootstrap 4. This helps prevent our stylesheets from getting bloated and makes it easier for things to work well across a wide range browsers & devices. Please take the time to Read the docs

Note there is a dark mode, so make sure things look good with the dark background as well.

HTML

The core functionality of dcrdata is server-side rendered in Go and designed to work well with javascript disabled. For users with javascript enabled, Turbolinks creates a persistent single page application that handles all HTML rendering.

.tmpl files are cached by the backend, and can be reloaded via running killall -USR1 dcrdata from the command line.

Javascript

To encourage code that is idiomatic to Turbolinks based execution environment, javascript based enhancements should use Stimulus controllers with corresponding actions and targets. Keeping things tightly scoped with controllers and modules helps to localize complexity and maintain a clean application lifecycle. When using events handlers, bind and unbind them in the connect and disconnect function of controllers which executes when they get removed from the DOM.

Web Performance

The core functionality of dcrdata should perform well in low power device / high latency scenarios (eg. a cheap smart phone with poor reception). This means that heavy assets should be lazy loaded when they are actually needed. Simple tasks like checking a transaction or address should have a very fast initial page load.

Helper Packages

package dbtypes defines the data types used by the DB backends to model the block, transaction, and related blockchain data structures. Functions for converting from standard Decred data types (e.g. wire.MsgBlock) are also provided.

package rpcutils includes helper functions for interacting with a rpcclient.Client.

package stakedb defines the StakeDatabase and ChainMonitor types for efficiently tracking live tickets, with the primary purpose of computing ticket pool value quickly. It uses the database.DB type from github.com/decred/dcrd/database with an ffldb storage backend from github.com/decred/dcrd/database/ffldb. It also makes use of the stake.Node type from github.com/decred/dcrd/blockchain/stake. The ChainMonitor type handles connecting new blocks and chain reorganization in response to notifications from dcrd.

package txhelpers includes helper functions for working with the common types dcrutil.Tx, dcrutil.Block, chainhash.Hash, and others.

Internal-use Packages

Some packages are currently designed only for internal use by other dcrdata packages, but may be of general value in the future.

blockdata defines:

  • The chainMonitor type and its BlockConnectedHandler() method that handles block-connected notifications and triggers data collection and storage.
  • The BlockData type and methods for converting to API types.
  • The blockDataCollector type and its Collect() and CollectHash() methods that are called by the chain monitor when a new block is detected.
  • The BlockDataSaver interface required by chainMonitor for storage of collected data.

dcrpg defines:

  • The ChainDB type, which is the primary exported type from dcrpg, providing an interface for a PostgreSQL database.
  • A large set of lower-level functions to perform a range of queries given a *sql.DB instance and various parameters.
  • The internal package contains the raw SQL statements.

package mempool defines a MempoolMonitor type that can monitor a node's mempool using the OnTxAccepted notification handler to send newly received transaction hashes via a designated channel. Ticket purchases (SSTx) are triggers for mempool data collection, which is handled by the DataCollector class, and data storage, which is handled by any number of objects implementing the MempoolDataSaver interface.

Plans

See the GitHub issue trackers and the project milestones.

Contributing

Yes, please! See CONTRIBUTING.md for details, but here's the gist of it:

  1. Fork the repo.
  2. Create a branch for your work (git checkout -b cool-stuff).
  3. Code something great.
  4. Commit and push to your repo.
  5. Create a pull request.

DO NOT merge from master to your feature branch; rebase.

Also, come chat with us on Matrix in the dcrdata channel!

Author: Decred
Source Code: https://github.com/decred/dcrdata 
License: ISC license

#go #golang #json #restapi #blockchain 

Dcrdata: Decred Block Explorer, with Packages, App for Data Collection

Building A Complete User Registry using Spring Boot API RESTful, JWT

Spring Boot API RESTful

A complete user registry, with access permissions, JWT token, integration and unit tests, using the RESTful API pattern.

Table of Contents

  • Features
  • Requirements
  • Entities
  • Installation
  • Running a specific test
  • Swagger
  • Database Migrations
  • Docker
  • Environment variables

Features

Tecnologias

Requirements

  • Postgres: ^13
  • Java: ^17
  • Maven: ^3.8.4

This project was started with Spring Initializr.

Entities

database diagram

🚨 draw.io file here

Installation

# clone the repository and access the directory.
$ git clone git@github.com:Throyer/springboot-api-crud.git && cd springboot-api-crud

# download dependencies
$ mvn install -DskipTests

# run the application
$ mvn spring-boot:run

# run the tests
$ mvn test

# to build for production
$ mvn clean package

# to generate the coverage report after testing (available at: target/site/jacoco/index.html)
$ mvn jacoco:report

Tests

Running a specific test

use the parameter -Dtest=<class>#<method>

for example the integration test. creating a user:

$ mvn test -Dtest=UsersControllerIntegrationTests#should_save_a_new_user

Swagger

Once the application is up, it is available at: localhost:8080/documentation

example on heroku

Database Migrations

Creating database migration files

🚨 make sure you have maven in your environment and that you are in the correct directory ./api

Java based migrations

mvn migration:generate -Dname=my-migration-name

SQL based migrations

mvn migration:generate -Dname=my-migration-name -Dsql

Docker examples

🚨 create environment file

 cp docker/.env.example docker/.env

docker compose development

docker-compose -p example-api-development -f ./docker/docker-compose.dev.yml --env-file ./docker/.env up -d --force-recreate

docker compose production

docker-compose -p example-api -f ./docker/docker-compose.prod.yml --env-file ./docker/.env up -d --build

or

# development up / down
scripts/dev.sh up
scripts/dev.sh down

# production up / down
scripts/prod.sh up
scripts/prod.sh down

Environment variables

DescriptionParameterDefault values
server portSERVER_PORT8080
database urlDB_URLlocalhost:5432/common_app
username (database)DB_USERNAMEroot
user password (database)DB_PASSWORDroot
displays the generated sql in the loggerDB_SHOW_SQLfalse
set maximum database connectionsDB_MAX_CONNECTIONS5
secret value in token generationTOKEN_SECRETsecret
token expiration time in hoursTOKEN_EXPIRATION_IN_HOURS24
refresh token expiry time in daysREFRESH_TOKEN_EXPIRATION_IN_DAYS7
SMTP server addressSMTP_HOSTsmtp.gmail.com
SMTP server portSMTP_PORT587
SMTP usernameSMTP_USERNAMEuser
SMTP server passwordSMTP_PASSWORDsecret
time for recovery email to expireMINUTES_TO_EXPIRE_RECOVERY_CODE20
max requests per minuteMAX_REQUESTS_PER_MINUTE10
swagger usernameSWAGGER_USERNAMEnull
swagger passwordSWAGGER_PASSWORDnull

these variables are defined in: application.properties

# to change the value of some environment variable at runtime
# on execution, just pass it as a parameter. (like --SERVER_PORT=80).
$ java -jar api-4.1.2.jar --SERVER_PORT=80

All options of aplication.properties here.

All features of Spring Boot.

Learn More 

Live demo on heroku

Demonstration

Download details:

Author: Throyer
Source code: https://github.com/Throyer/springboot-api-rest-example
License: GPL-3.0 license

#spring #springboot #java #restapi #jwt #swagger

Building A Complete User Registry using Spring Boot API RESTful, JWT
Dylan  Iqbal

Dylan Iqbal

1659401219

How to Build a REST API with .NET 6

In this tutorial, you'll learn how to build an industry level REST API from scratch with .NET 6

Learn to use .NET 6 to build a REST API. This is a concise, start-to-finish course that developers can use as a template to onboard/structure small to medium sized industry-level CRUD applications.

⭐️ Course Contents ⭐️
⌨️ (00:00) Introduction
⌨️ (03:29) Backend server architecture
⌨️ (11:53) Implementing logic of API model
⌨️ (16:40) Testing API requests
⌨️ (20:04) Refactoring routes
⌨️ (20:45) Create model for request data
⌨️ (28:01) Create service interface
⌨️ (30:47) Implement additional methods
⌨️ (36:54) Handling errors
⌨️ (41:10) Refactoring controller and services
⌨️ (1:00:52) Refactoring error handling
⌨️ (1:02:40) Testing API requests
⌨️ (1:05:46) Conclusion

💻 Code: https://github.com/amantinband/buber-breakfast

#dotnet #api #restapi 

How to Build a REST API with .NET 6

How to Build REST APIs in Java with Spring Boot

In this live coding session, you will learn how to build REST APIs in Java with Spring Boot. You will learn how to bootstrap your application using https://start.spring.io and the New Project Wizard in IntelliJ. You will learn some best practices to keep in my while creating your APIs. By the end of this session, you will be able to create a basic CRUD REST API in Spring Boot.

Agenda

  • Introduction
    • Agenda
    • About Me
    • What is an API
    • What is REST
  • Create a new Spring Boot Project
    • start.spring.io
    • IntelliJ Initializr
  • Model (this is the resource)
    • LiveStream (Mutable and Immutable)
    • Unit Tests
    • Move to a Record
  • Controller
  • Repository
  • Dependency Injection (IoC)
  • LiveStream Controller CRUD methods
  • Spring Bean Validation
  • Controller Integration Tests

IntelliJ Plugins

I was asked a lot of questions about which plugins I use for IntelliJ. I am using 2021.3 Ultimate Edition at the time of this recording. The plugins I was asked about the most are:

I created a video on Github Copilot for Java developers https://youtu.be/97C3fQqzj-I

Recording: https://www.youtube.com/watch?v=q_RLfOB7axQ&t=2315s

Download details:
Author: danvega
Source code: https://github.com/danvega/building-rest-apis-spring-boot
License:

#spring #java #springboot #restapi

How to Build REST APIs in Java with Spring Boot

Cakephp Realworld Example App

Example CakePHP codebase containing real world examples (CRUD, auth, advanced patterns and more) that adheres to the RealWorld spec and API.

This repo is functionality complete — PRs and issues welcome!


Getting started

Installation

Clone the repository

git clone git@github.com:gothinkster/cakephp-realworld-example-app.git

Switch to the repo folder

cd cakephp-realworld-example-app

Install all the dependencies using composer

composer install

Configure your database settings in the config/app.php file(See: Datasource/default)

vi config/app.php

Run the database migrations (Set the database connection in app.php)

bin/cake migrations migrate

Start the local development server

bin/cake server

You can now access the server at http://localhost:8765

Database seeding

Populate the database with seed data with relationships which includes users, articles, comments, tags, favorites and follows. This can help you to quickly start testing the api or couple a frontend and start using it with ready content.

Run the database seeder and you're done

bin/cake migrations seed

API Specification

This application adheres to the api specifications set by the Thinkster team. This helps mix and match any backend with any other frontend without conflicts.

Full API Spec

For more information on how to this works with other frontends/backends, head over to the RealWorld repo.

How it works

Please check the official cakephp installation guide for server requirements before you start. Official Documentation


Code overview

Dependencies

Folders

  • src - Contains all the application logic.
  • config - Contains all the application configuration files.
  • src/Model/Entity - Contains all cakephp ORM entites.
  • src/Model/Table - Contains all cakephp ORM tables.
  • src/Service - Contains application services that represents root api endpoints.
  • src/Service/Action - Contains application endpoints logic logic.
  • src/Service/Renderer - Contains the final api response formatter.
  • /config/Migrations - Contains all the database migrations.

Environment configuration

  • config/app.php - Configuration settings can be set in this file

Note : You can quickly set the database information and other variables in this file and have the application fully working.


Testing API

Run the cakephp development server

bin/cake server

The api can now be accessed at

http://localhost:8765/api

Request headers

RequiredKeyValue
YesContent-Typeapplication/json
YesX-Requested-WithXMLHttpRequest
OptionalAuthorizationToken {JWT}

Refer the api specification for more info.


Authentication

This applications uses JSON Web Token (JWT) to handle authentication. The token is passed with each request using the Authorization header with Token scheme. The cakephp authenticate middleware configured for handling JWT authentication and validation and authentication of the token. Please check the following sources to learn more about JWT.


Cross-Origin Resource Sharing (CORS)

This applications has CORS enabled by default on all API endpoints. Please check the following sources to learn more about CORS.

Author: Gothinkster
Source Code: https://github.com/gothinkster/cakephp-realworld-example-app 
License: View license

#php #cakephp #app #restapi 

Cakephp Realworld Example App

jQueryDataTablesをVue2アプリに統合する方法

jQueryDatatablesを使用してVuejsで動的テーブルを作成する方法を知りたい場合は、このチュートリアルの最後まで進んでください。

データテーブルの主な用途は、ユーザーが一度にデータを簡単にスキャンできるように、データを簡単に表示することです。単純な情報や短い情報を表示することは、ユーザーインターフェイスでは大きな課題ではありません。

ユーザーエクスペリエンスの観点からの深刻な課題は、数百、数千、またはそれ以上のレコードがある場合に発生します。

今日のvuejsjQueryデータテーブルチュートリアルでは、DataTablesを介して大量のデータを管理するという同様の状況に取り組みます。jQueryDataTablesライブラリを使用してVuejsアプリケーションでデータテーブルを作成する方法を説明します。

VuejsでjQueryDataTablesを使用してデータを行と列の形式で表示する適切で簡単な方法を紹介するだけでなく、このチュートリアルを気に入っていただけると思います。

Node.jsギャツビーエラー–「デジタルエンベロープルーチン::サポートされていません…」

Error: digital envelope routines::unsupported
opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
library: 'digital envelope routines',
reason: 'unsupported',
code: 'ERR_OSSL_EVP_UNSUPPORTED'

アプリを呼び出す際の上記のエラーを削除するには、 package.jsonファイルの"scripts": []配列を必ず更新してください。

"scripts": {
    "serve": "export NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve",
    "build": "export NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service build",
    "lint": "export NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service lint"
},

jQueryDataTablesをVue2アプリに統合する方法

  • ステップ1: Vueプロジェクトを作成する
  • ステップ2: Datatables +jQuery+ブートストラップパッケージ/liをインストールする>
  • ステップ3: Axiosライブラリをインストールする
  • ステップ4: jQueryDataTableコンポーネントを作成する
  • ステップ5: DataTableコンポーネントを登録する
  • ステップ6: Vueアプリケーションを実行する

Vueプロジェクトを作成する

まず、コマンドを実行してvuecliツールをインストールします。

npm install -g @vue/cli

次に、commandと入力し、Enterキーを押して、新しいvuejsアプリのダウンロードを開始します。cliは、アプリのバージョンを選択するように求めます。vue2または3を選択できます。

vue create vue-datatable-demo

プロジェクトのルートに足を踏み入れます。

cd vue-datatable-demo

Datatables +jQuery+ブートストラップパッケージを追加する

全体として次のコマンドを入力して、vue jsプロジェクトにjQuery、datatables、およびブートストラップパッケージをインストールします。

npm install jquery datatables.net-dt bootstrap

Axiosライブラリをインストールする

JSONデータをvueテーブルに表示します。Axiosパッケージに完全に依存するAPIからデータを取得するにはRESTAPIが必要になるため、Axiosパッケージをインストールします。

npm install axios

jQueryDataTableコンポーネントを作成する

すべてのライブラリがvuejsアプリに追加されました。このセクションでは、すべてのパッケージを蓄積して、vueアプリでデータを体系的に表示するためのjQueryデータテーブルを作成する方法を示します。

コンポーネントフォルダにJqueryTable.vueファイルを作成し、その後、以下のコード全体をcomponents/JqueryTable.vueテンプレートに配置します。

<template>
  <div>
    <h2>Implement jQuery DataTable in Vue Js</h2>
    <table class="table" id="datatable">
      <thead>
        <tr>
          <th>ID</th>
          <th>Product Title</th>
          <th>Product Price</th>
          <th>Created On</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="item in products" :key="item.id">
          <td>{{ item.id }}</td>
          <td>{{ item.product_title }}</td>
          <td>{{ item.product_price }}</td>
          <td>{{ item.created_at }}</td>
        </tr>
      </tbody>
    </table>
  </div>
</template>
<script>
import "jquery/dist/jquery.min.js";
import "bootstrap/dist/css/bootstrap.min.css";
import "datatables.net-dt/js/dataTables.dataTables";
import "datatables.net-dt/css/jquery.dataTables.min.css";
import axios from "axios";
import $ from "jquery";
export default {
  mounted() {
    axios.get("API_Goes_Here").then((response) => {
      this.products = response.data;
      $("#datatable").DataTable();
    });
  },
  data: function () {
    return {
      products: [],
    };
  },
};
</script>

DataTableコンポーネントを登録する

コンポーネントはプライマリApp.vueファイルに登録する必要があります。必ず、推奨ファイルに追加してください。

<template>
  <div class="container mt-4">
    <JqueryTable/>
  </div>
</template>
<script>
import JqueryTable from './components/JqueryTable.vue'
export default {
  name: 'App',
  components: {
    JqueryTable
  }
}
</script>
<style>
  .container {
    max-width: 1000px;
  }
</style>

Vueアプリケーションを実行する

ターミナル画面に移動し、次のコマンドの入力を開始して、ブラウザーでvueアプリを実行します。

npm run serve
http://localhost:8080

VueにjQueryデータテーブルを追加する

結論

この包括的なVuejsjQueryデータテーブルの例では、jQueryデータテーブルをvuejsアプリに統合するのに役立つ可能性のあるいくつかの露骨な情報を共有しました。

だけでなく、AxiosとJSONサーバーを使用してデータをデータテーブルに動的に表示し、注目すべきjQueryデータテーブルパッケージを使用してVuejsアプリケーションのRESTAPIを表示するのにも役立ちます。

ソース:https ://www.positronx.io/vue-js-dynamic-jquery-datatables-tutorial-example/

#vuej #jquery #datatable #json #restapi 

jQueryDataTablesをVue2アプリに統合する方法
Iara  Simões

Iara Simões

1657879200

Como Integrar JQuery DataTables No Aplicativo Vue 2

Se você quer saber como criar uma tabela dinâmica em Vue js usando o jQuery Datatables, então vá até o final deste tutorial.

O principal uso de uma tabela de dados é exibir dados de maneira fácil para que um usuário possa varrer facilmente os dados de uma só vez. Mostrar informações simples ou curtas não é um grande desafio na interface do usuário.

O profundo desafio do ponto de vista da experiência do usuário surge quando há centenas, milhares ou até mais registros.

No tutorial de datatable vue js jQuery de hoje, abordaremos uma situação semelhante de gerenciamento de uma grande quantidade de dados por meio de DataTables. Vamos ensinar como criar datatable na aplicação Vue js usando a biblioteca jQuery DataTables.

Não apenas mostraremos a maneira correta e fácil de usar o jQuery DataTables no Vue js para exibir os dados no formato de linhas e colunas e nossa noção nos diz que você vai adorar este tutorial.

Erro no Node.js Gatsby – “rotinas de envelope digital:: não suportado …”

Error: digital envelope routines::unsupported
opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
library: 'digital envelope routines',
reason: 'unsupported',
code: 'ERR_OSSL_EVP_UNSUPPORTED'

Para remover o erro acima para invocar o aplicativo, certifique-se de atualizar a "scripts": []matriz no arquivo package.json .

"scripts": {
    "serve": "export NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve",
    "build": "export NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service build",
    "lint": "export NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service lint"
},

Como integrar jQuery DataTables no aplicativo Vue 2

  • Passo 1: Criar Projeto Vue
  • Etapa 2: Instalar Datatables + jQuery + Bootstrap Packages/li>
  • Etapa 3: instalar a biblioteca do Axios
  • Etapa 4: criar o componente DataTable do jQuery
  • Etapa 5: registrar o componente DataTable
  • Etapa 6: execute o aplicativo Vue

Criar projeto Vue

Primeiro, execute o comando para instalar a ferramenta vue cli.

npm install -g @vue/cli

Em segundo lugar, digite command e pressione enter para iniciar o download de um novo aplicativo vue js; cli peça para você escolher a versão do aplicativo, você pode escolher vue 2 ou 3.

vue create vue-datatable-demo

Entre na raiz do projeto.

cd vue-datatable-demo

Adicionar Datatables + jQuery + Pacotes Bootstrap

Ao todo, digite os seguintes comandos para instalar jQuery, datatables e pacotes de bootstrap no projeto vue js.

npm install jquery datatables.net-dt bootstrap

Instalar a biblioteca do Axios

Mostraremos os dados JSON na tabela vue; precisaremos de uma API REST para obter os dados da API que depende totalmente do pacote Axios, então instale o pacote Axios.

npm install axios

Criar componente jQuery DataTable

Todas as bibliotecas foram adicionadas ao aplicativo vue js; esta seção mostrará como acumular todos os pacotes para criar uma tabela de dados jQuery para exibir dados sistematicamente no aplicativo vue.

Crie o arquivo JqueryTable.vue na pasta de componentes, depois coloque todo o código abaixo no template components/JqueryTable.vue .

<template>
  <div>
    <h2>Implement jQuery DataTable in Vue Js</h2>
    <table class="table" id="datatable">
      <thead>
        <tr>
          <th>ID</th>
          <th>Product Title</th>
          <th>Product Price</th>
          <th>Created On</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="item in products" :key="item.id">
          <td>{{ item.id }}</td>
          <td>{{ item.product_title }}</td>
          <td>{{ item.product_price }}</td>
          <td>{{ item.created_at }}</td>
        </tr>
      </tbody>
    </table>
  </div>
</template>
<script>
import "jquery/dist/jquery.min.js";
import "bootstrap/dist/css/bootstrap.min.css";
import "datatables.net-dt/js/dataTables.dataTables";
import "datatables.net-dt/css/jquery.dataTables.min.css";
import axios from "axios";
import $ from "jquery";
export default {
  mounted() {
    axios.get("API_Goes_Here").then((response) => {
      this.products = response.data;
      $("#datatable").DataTable();
    });
  },
  data: function () {
    return {
      products: [],
    };
  },
};
</script>

Registrar o componente DataTable

Os componentes devem ser registrados no arquivo App.vue primário , certifique-se de adicioná-lo ao arquivo recomendado.

<template>
  <div class="container mt-4">
    <JqueryTable/>
  </div>
</template>
<script>
import JqueryTable from './components/JqueryTable.vue'
export default {
  name: 'App',
  components: {
    JqueryTable
  }
}
</script>
<style>
  .container {
    max-width: 1000px;
  }
</style>

Executar aplicativo Vue

Vá para a tela do terminal, comece a digitar o seguinte comando e execute o aplicativo vue no navegador.

npm run serve
http://localhost:8080

adicionar tabelas de dados jQuery no Vue

Conclusão

Neste exemplo abrangente de tabela de dados jQuery do Vue js, compartilhamos algumas informações flagrantes que podem ajudá-lo a integrar as tabelas de dados do jQuery no aplicativo vue js.

Não apenas, mas também ajuda a exibir dados dinamicamente em uma tabela de dados usando o servidor Axios e JSON e uma API REST no aplicativo Vue js usando o notável pacote de tabela de dados jQuery.

Fonte: https://www.positronx.io/vue-js-dynamic-jquery-datatables-tutorial-example/

#vuej #jquery #datatable #json #restapi 

Como Integrar JQuery DataTables No Aplicativo Vue 2
Anne  de Morel

Anne de Morel

1657878304

Comment Intégrer jQuery DataTables dans l'application Vue 2

Si vous voulez savoir comment créer une table dynamique dans Vue js à l'aide de jQuery Datatables, continuez jusqu'à la fin de ce didacticiel.

L'utilisation principale d'un tableau de données est d'afficher les données de manière simple afin qu'un utilisateur puisse facilement numériser les données en une seule fois. L'affichage d'informations simples ou courtes n'est pas un grand défi dans l'interface utilisateur.

Le défi profond du point de vue de l'expérience utilisateur survient lorsqu'il y a des centaines, des milliers ou même plus d'enregistrements.

Dans le tutoriel vue js jQuery datatable d'aujourd'hui, nous aborderons une situation similaire de gestion d'une grande quantité de données via DataTables. Nous allons vous apprendre à créer une table de données dans l'application Vue js à l'aide de la bibliothèque jQuery DataTables.

Non seulement nous vous montrerons la manière appropriée et facile d'utiliser jQuery DataTables dans Vue js pour afficher les données au format lignes et colonnes et notre idée nous dit que vous allez adorer ce tutoriel.

Erreur Node.js Gatsby - "routines d'enveloppe numérique :: non prises en charge ..."

Error: digital envelope routines::unsupported
opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
library: 'digital envelope routines',
reason: 'unsupported',
code: 'ERR_OSSL_EVP_UNSUPPORTED'

Pour supprimer l'erreur ci-dessus lors de l'appel de l'application, assurez-vous de mettre à jour le "scripts": []tableau dans le fichier package.json .

"scripts": {
    "serve": "export NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve",
    "build": "export NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service build",
    "lint": "export NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service lint"
},

Comment intégrer jQuery DataTables dans l'application Vue 2

  • Étape 1 : Créer un projet Vue
  • Étape 2 : Installez Datatables + jQuery + Bootstrap Packages/li>
  • Étape 3 : Installer la bibliothèque Axios
  • Étape 4 : Créer un composant jQuery DataTable
  • Étape 5 : enregistrer le composant DataTable
  • Étape 6 : Exécuter l'application Vue

Créer un projet Vue

Tout d'abord, exécutez la commande pour installer l'outil vue cli.

npm install -g @vue/cli

Deuxièmement, tapez la commande et appuyez sur Entrée pour commencer à télécharger une nouvelle application vue js ; cli vous demande de choisir la version de l'application, vous pouvez choisir vue 2 ou 3.

vue create vue-datatable-demo

Accédez à la racine du projet.

cd vue-datatable-demo

Ajouter des packages Datatables + jQuery + Bootstrap

Au total, tapez les commandes suivantes pour installer les packages jQuery, datatables et bootstrap dans le projet vue js.

npm install jquery datatables.net-dt bootstrap

Installer la bibliothèque Axios

Nous allons afficher les données JSON dans la table vue ; nous aurons besoin d'une API REST pour obtenir les données de l'API qui repose entièrement sur le package Axios, installez donc le package Axios.

npm install axios

Créer un composant jQuery DataTable

Toutes les bibliothèques ont été ajoutées à l'application vue js ; cette section vous montrera comment accumuler tous les packages pour créer une table de données jQuery pour afficher les données systématiquement dans l'application vue.

Créez le fichier JqueryTable.vue dans le dossier des composants, puis placez l'ensemble du code ci-dessous dans le modèle components/JqueryTable.vue .

<template>
  <div>
    <h2>Implement jQuery DataTable in Vue Js</h2>
    <table class="table" id="datatable">
      <thead>
        <tr>
          <th>ID</th>
          <th>Product Title</th>
          <th>Product Price</th>
          <th>Created On</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="item in products" :key="item.id">
          <td>{{ item.id }}</td>
          <td>{{ item.product_title }}</td>
          <td>{{ item.product_price }}</td>
          <td>{{ item.created_at }}</td>
        </tr>
      </tbody>
    </table>
  </div>
</template>
<script>
import "jquery/dist/jquery.min.js";
import "bootstrap/dist/css/bootstrap.min.css";
import "datatables.net-dt/js/dataTables.dataTables";
import "datatables.net-dt/css/jquery.dataTables.min.css";
import axios from "axios";
import $ from "jquery";
export default {
  mounted() {
    axios.get("API_Goes_Here").then((response) => {
      this.products = response.data;
      $("#datatable").DataTable();
    });
  },
  data: function () {
    return {
      products: [],
    };
  },
};
</script>

Enregistrer le composant DataTable

Les composants doivent être enregistrés dans le fichier principal App.vue , assurez-vous de l'ajouter dans le fichier recommandé.

<template>
  <div class="container mt-4">
    <JqueryTable/>
  </div>
</template>
<script>
import JqueryTable from './components/JqueryTable.vue'
export default {
  name: 'App',
  components: {
    JqueryTable
  }
}
</script>
<style>
  .container {
    max-width: 1000px;
  }
</style>

Exécuter l'application Vue

Rendez-vous sur l'écran du terminal, commencez à taper la commande suivante et exécutez l'application vue dans le navigateur.

npm run serve
http://localhost:8080

ajouter des tables de données jQuery dans Vue

Conclusion

Dans cet exemple complet de table de données Vue js jQuery, nous avons partagé des informations flagrantes qui pourraient vous aider à intégrer des tables de données jQuery dans l'application vue js.

Non seulement, mais vous aide également à afficher les données de manière dynamique dans une table de données à l'aide du serveur Axios et JSON et d'une API REST dans l'application Vue js à l'aide du remarquable package jQuery datatable.

Source : https://www.positronx.io/vue-js-dynamic-jquery-datatables-tutorial-example/

#vuej #jquery #datatable #json #restapi 

Comment Intégrer jQuery DataTables dans l'application Vue 2
郝 玉华

郝 玉华

1657878240

如何在 Vue 2 应用程序中集成 jQuery DataTables

如果您想知道如何使用 jQuery 数据表在 Vue js 中创建动态表,请继续阅读本教程。

数据表的主要用途是以简单的方式显示数据,以便用户可以轻松地一次扫描数据。在用户界面中显示简单或简短的信息并不是什么大挑战。

当有成百上千甚至更多的记录时,从用户体验的角度来看,就会出现深刻的挑战。

在今天的 vue js jQuery 数据表教程中,我们将解决通过 DataTables 管理大量数据的类似情况。我们将教你如何使用 jQuery DataTables 库在 Vue js 应用程序中创建数据表。

不仅我们将向您展示在 Vue js 中使用 jQuery DataTables 以行和列格式显示数据的正确且简单的方法,而且我们的理念告诉我们您会喜欢本教程。

Node.js Gatsby 错误——“数字信封例程::不支持……”

Error: digital envelope routines::unsupported
opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
library: 'digital envelope routines',
reason: 'unsupported',
code: 'ERR_OSSL_EVP_UNSUPPORTED'

要删除调用应用程序的上述错误,请确保更新package.json文件"scripts": []中的数组。

"scripts": {
    "serve": "export NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve",
    "build": "export NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service build",
    "lint": "export NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service lint"
},

如何在 Vue 2 应用程序中集成 jQuery DataTables

  • 第 1 步:创建 Vue 项目
  • 第二步:安装 Datatables + jQuery + Bootstrap Packages/li>
  • 第三步:安装 Axios 库
  • 第 4 步:创建 jQuery 数据表组件
  • 步骤 5:注册 DataTable 组件
  • 第 6 步:运行 Vue 应用程序

创建 Vue 项目

首先,运行命令安装 vue cli 工具。

npm install -g @vue/cli

其次,输入命令并回车,开始下载一个新的 vue js 应用;cli要求您选择应用程序的版本,您可以选择vue 2或3。

vue create vue-datatable-demo

进入项目的根目录。

cd vue-datatable-demo

添加数据表 + jQuery + Bootstrap 包

总共键入以下命令以在 vue js 项目中安装 jQuery、数据表和引导程序包。

npm install jquery datatables.net-dt bootstrap

安装 Axios 库

我们将在 vue 表中显示 JSON 数据;我们将需要一个 REST API 来从完全依赖 Axios 包的 API 获取数据,因此请安装 Axios 包。

npm install axios

创建 jQuery 数据表组件

所有的库都已添加到 vue js 应用程序中;本节将向您展示如何累积所有包以创建 jQuery 数据表,以便在 vue 应用程序中系统地显示数据。

在 components 文件夹中创建 JqueryTable.vue 文件,然后将下面给出的整个代码放在components/JqueryTable.vue模板中。

<template>
  <div>
    <h2>Implement jQuery DataTable in Vue Js</h2>
    <table class="table" id="datatable">
      <thead>
        <tr>
          <th>ID</th>
          <th>Product Title</th>
          <th>Product Price</th>
          <th>Created On</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="item in products" :key="item.id">
          <td>{{ item.id }}</td>
          <td>{{ item.product_title }}</td>
          <td>{{ item.product_price }}</td>
          <td>{{ item.created_at }}</td>
        </tr>
      </tbody>
    </table>
  </div>
</template>
<script>
import "jquery/dist/jquery.min.js";
import "bootstrap/dist/css/bootstrap.min.css";
import "datatables.net-dt/js/dataTables.dataTables";
import "datatables.net-dt/css/jquery.dataTables.min.css";
import axios from "axios";
import $ from "jquery";
export default {
  mounted() {
    axios.get("API_Goes_Here").then((response) => {
      this.products = response.data;
      $("#datatable").DataTable();
    });
  },
  data: function () {
    return {
      products: [],
    };
  },
};
</script>

注册数据表组件

组件必须在主App.vue文件中注册,确保将其添加到推荐文件中。

<template>
  <div class="container mt-4">
    <JqueryTable/>
  </div>
</template>
<script>
import JqueryTable from './components/JqueryTable.vue'
export default {
  name: 'App',
  components: {
    JqueryTable
  }
}
</script>
<style>
  .container {
    max-width: 1000px;
  }
</style>

运行 Vue 应用程序

转到终端屏幕,开始输入以下命令并在浏览器中运行 vue 应用程序。

npm run serve
http://localhost:8080

在 Vue 中添加 jQuery 数据表

结论

在这个全面的 Vue js jQuery 数据表示例中,我们分享了一些公然的信息,这些信息可能会帮助您将 jQuery 数据表集成到 Vue js 应用程序中。

不仅可以帮助您使用 Axios 和 JSON 服务器动态地将数据显示到数据表中,还可以使用著名的 jQuery 数据表包在 Vue js 应用程序中使用 REST API 将数据动态显示到数据表中。

来源:https ://www.positronx.io/vue-js-dynamic-jquery-datatables-tutorial-example/

#vuej #jquery #datatable #json #restapi 

如何在 Vue 2 应用程序中集成 jQuery DataTables
Thai  Son

Thai Son

1657874340

Cách Tích Hợp JQuery DataTables Trong ứng Dụng Vue 2

Nếu bạn muốn biết cách tạo một bảng động trong Vue js bằng cách sử dụng jQuery Datatables, hãy làm cho đến cuối hướng dẫn này.

Công dụng chính của bảng dữ liệu là hiển thị dữ liệu một cách dễ dàng để người dùng có thể dễ dàng quét dữ liệu trong một lần. Hiển thị thông tin đơn giản hoặc ngắn gọn không phải là một thách thức lớn trong giao diện người dùng.

Thách thức sâu sắc từ quan điểm trải nghiệm người dùng nảy sinh khi có hàng trăm, hàng nghìn hoặc thậm chí nhiều bản ghi hơn.

Trong hướng dẫn lập trình dữ liệu vue js jQuery hôm nay, chúng ta sẽ giải quyết một tình huống tương tự khi quản lý một lượng lớn dữ liệu thông qua DataTables. Chúng tôi sẽ dạy bạn cách tạo dữ liệu trong ứng dụng Vue js bằng thư viện jQuery DataTables.

Không chỉ vậy, chúng tôi sẽ chỉ cho bạn cách thích hợp và dễ dàng để sử dụng jQuery DataTables trong Vue js để hiển thị dữ liệu ở định dạng hàng và cột và quan điểm của chúng tôi cho chúng tôi biết rằng bạn sẽ thích hướng dẫn này.

Lỗi Node.js Gatsby - “quy trình phong bì kỹ thuật số :: không được hỗ trợ…”

Error: digital envelope routines::unsupported
opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
library: 'digital envelope routines',
reason: 'unsupported',
code: 'ERR_OSSL_EVP_UNSUPPORTED'

Để loại bỏ lỗi trên khi gọi ứng dụng, hãy đảm bảo cập nhật "scripts": []mảng trong tệp package.json .

"scripts": {
    "serve": "export NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve",
    "build": "export NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service build",
    "lint": "export NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service lint"
},

Cách tích hợp jQuery DataTables trong ứng dụng Vue 2

  • Bước 1: Tạo Vue Project
  • Bước 2: Cài đặt Datatables + jQuery + Bootstrap Packages / li>
  • Bước 3: Cài đặt Thư viện Axios
  • Bước 4: Tạo thành phần jQuery DataTable
  • Bước 5: Đăng ký thành phần DataTable
  • Bước 6: Chạy ứng dụng Vue

Tạo dự án Vue

Đầu tiên, chạy lệnh để cài đặt công cụ vue cli.

npm install -g @vue/cli

Thứ hai, gõ lệnh và nhấn enter để bắt đầu tải xuống ứng dụng vue js mới; bấm yêu cầu bạn chọn phiên bản của ứng dụng, bạn có thể chọn vue 2 hoặc 3.

vue create vue-datatable-demo

Bước vào thư mục gốc của dự án.

cd vue-datatable-demo

Thêm các gói dữ liệu dữ liệu + jQuery + Bootstrap

Nhập hoàn toàn các lệnh sau để cài đặt các gói jQuery, datatables và bootstrap trong dự án vue js.

npm install jquery datatables.net-dt bootstrap

Cài đặt Thư viện Axios

Chúng tôi sẽ hiển thị dữ liệu JSON trong bảng vue; chúng ta sẽ cần một REST API để lấy dữ liệu từ API hoàn toàn dựa vào gói Axios, vì vậy hãy cài đặt gói Axios.

npm install axios

Tạo thành phần jQuery DataTable

Tất cả các thư viện đã được thêm vào ứng dụng vue js; phần này sẽ chỉ cho bạn cách tích lũy tất cả các gói để tạo ra một dữ liệu jQuery để hiển thị dữ liệu một cách có hệ thống trong ứng dụng vue.

Tạo tệp JqueryTable.vue trong thư mục thành phần, ở đó sau khi đặt toàn bộ mã đã cho bên dưới vào mẫu các thành phần / JqueryTable.vue .

<template>
  <div>
    <h2>Implement jQuery DataTable in Vue Js</h2>
    <table class="table" id="datatable">
      <thead>
        <tr>
          <th>ID</th>
          <th>Product Title</th>
          <th>Product Price</th>
          <th>Created On</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="item in products" :key="item.id">
          <td>{{ item.id }}</td>
          <td>{{ item.product_title }}</td>
          <td>{{ item.product_price }}</td>
          <td>{{ item.created_at }}</td>
        </tr>
      </tbody>
    </table>
  </div>
</template>
<script>
import "jquery/dist/jquery.min.js";
import "bootstrap/dist/css/bootstrap.min.css";
import "datatables.net-dt/js/dataTables.dataTables";
import "datatables.net-dt/css/jquery.dataTables.min.css";
import axios from "axios";
import $ from "jquery";
export default {
  mounted() {
    axios.get("API_Goes_Here").then((response) => {
      this.products = response.data;
      $("#datatable").DataTable();
    });
  },
  data: function () {
    return {
      products: [],
    };
  },
};
</script>

Đăng ký thành phần DataTable

Các thành phần phải được đăng ký trong tệp App.vue chính , hãy đảm bảo thêm nó vào tệp được đề xuất.

<template>
  <div class="container mt-4">
    <JqueryTable/>
  </div>
</template>
<script>
import JqueryTable from './components/JqueryTable.vue'
export default {
  name: 'App',
  components: {
    JqueryTable
  }
}
</script>
<style>
  .container {
    max-width: 1000px;
  }
</style>

Chạy ứng dụng Vue

Đi tới màn hình đầu cuối, bắt đầu nhập lệnh sau và chạy ứng dụng vue trong trình duyệt.

npm run serve
http://localhost:8080

thêm dữ liệu jQuery trong Vue

Sự kết luận

Trong ví dụ toàn diện về dữ liệu jQuery Vue js này, chúng tôi đã chia sẻ một số thông tin rõ ràng có thể giúp bạn tích hợp các tệp dữ liệu jQuery trong ứng dụng vue js.

Không chỉ mà còn giúp bạn hiển thị dữ liệu động thành bảng dữ liệu bằng máy chủ Axios và JSON và API REST trong ứng dụng Vue js bằng cách sử dụng gói dữ liệu jQuery đáng chú ý.

Nguồn: https://www.positronx.io/vue-js-dynamic-jquery-datatables-tutorial-example/

#vuej #jquery #datatable #json #restapi 

Cách Tích Hợp JQuery DataTables Trong ứng Dụng Vue 2
Diego  Elizondo

Diego Elizondo

1657873860

Cómo Integrar JQuery DataTables En La Aplicación Vue 2

Si desea saber cómo crear una tabla dinámica en Vue js utilizando jQuery Datatables, continúe hasta el final de este tutorial.

El uso principal de una tabla de datos es mostrar datos de una manera fácil para que un usuario pueda escanear fácilmente los datos de una sola vez. Mostrar información simple o corta no es un gran desafío en la interfaz de usuario.

El gran desafío desde el punto de vista de la experiencia del usuario surge cuando hay cientos, miles o incluso más registros.

En el tutorial de tabla de datos de vue js jQuery de hoy, abordaremos una situación similar de administración de una gran cantidad de datos a través de tablas de datos. Le enseñaremos cómo crear una tabla de datos en la aplicación Vue js utilizando la biblioteca jQuery DataTables.

No solo le mostraremos la manera adecuada y fácil de usar jQuery DataTables en Vue js para mostrar los datos en formato de filas y columnas y nuestra noción nos dice que le encantará este tutorial.

Error de Node.js Gatsby: "rutinas de sobres digitales:: no admitidas ..."

Error: digital envelope routines::unsupported
opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
library: 'digital envelope routines',
reason: 'unsupported',
code: 'ERR_OSSL_EVP_UNSUPPORTED'

Para eliminar el error anterior para invocar la aplicación, asegúrese de actualizar la "scripts": []matriz en el archivo package.json .

"scripts": {
    "serve": "export NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve",
    "build": "export NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service build",
    "lint": "export NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service lint"
},

Cómo integrar jQuery DataTables en la aplicación Vue 2

  • Paso 1: Crear Proyecto Vue
  • Paso 2: Instale Datatables + jQuery + Bootstrap Packages/li>
  • Paso 3: Instale la biblioteca Axios
  • Paso 4: Crear el componente jQuery DataTable
  • Paso 5: Registre el componente DataTable
  • Paso 6: Ejecute la aplicación Vue

Crear proyecto Vue

Primero, ejecute el comando para instalar la herramienta vue cli.

npm install -g @vue/cli

En segundo lugar, escriba comando y presione enter para comenzar a descargar una nueva aplicación vue js; cli le pide que elija la versión de la aplicación, puede elegir vue 2 o 3.

vue create vue-datatable-demo

Entra en la raíz del proyecto.

cd vue-datatable-demo

Agregue tablas de datos + jQuery + paquetes Bootstrap

En conjunto, escriba los siguientes comandos para instalar jQuery, tablas de datos y paquetes de arranque en el proyecto vue js.

npm install jquery datatables.net-dt bootstrap

Instalar la biblioteca Axios

Mostraremos los datos JSON en la tabla vue; necesitaremos una API REST para obtener los datos de la API que depende completamente del paquete Axios, así que instale el paquete Axios.

npm install axios

Crear componente jQuery DataTable

Todas las bibliotecas se han agregado a la aplicación vue js; esta sección le mostrará cómo acumular todos los paquetes para crear una tabla de datos jQuery para mostrar datos sistemáticamente en la aplicación vue.

Cree el archivo JqueryTable.vue en la carpeta de componentes, luego coloque todo el código que se indica a continuación en la plantilla components/JqueryTable.vue .

<template>
  <div>
    <h2>Implement jQuery DataTable in Vue Js</h2>
    <table class="table" id="datatable">
      <thead>
        <tr>
          <th>ID</th>
          <th>Product Title</th>
          <th>Product Price</th>
          <th>Created On</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="item in products" :key="item.id">
          <td>{{ item.id }}</td>
          <td>{{ item.product_title }}</td>
          <td>{{ item.product_price }}</td>
          <td>{{ item.created_at }}</td>
        </tr>
      </tbody>
    </table>
  </div>
</template>
<script>
import "jquery/dist/jquery.min.js";
import "bootstrap/dist/css/bootstrap.min.css";
import "datatables.net-dt/js/dataTables.dataTables";
import "datatables.net-dt/css/jquery.dataTables.min.css";
import axios from "axios";
import $ from "jquery";
export default {
  mounted() {
    axios.get("API_Goes_Here").then((response) => {
      this.products = response.data;
      $("#datatable").DataTable();
    });
  },
  data: function () {
    return {
      products: [],
    };
  },
};
</script>

Registrar componente DataTable

Los componentes deben registrarse en el archivo App.vue principal , asegúrese de agregarlo al archivo recomendado.

<template>
  <div class="container mt-4">
    <JqueryTable/>
  </div>
</template>
<script>
import JqueryTable from './components/JqueryTable.vue'
export default {
  name: 'App',
  components: {
    JqueryTable
  }
}
</script>
<style>
  .container {
    max-width: 1000px;
  }
</style>

Ejecutar la aplicación Vue

Dirígete a la pantalla de la terminal, comienza a escribir el siguiente comando y ejecuta la aplicación vue en el navegador.

npm run serve
http://localhost:8080

agregar tablas de datos jQuery en Vue

Conclusión

En este completo ejemplo de tabla de datos jQuery de Vue js, compartimos información evidente que podría ayudarlo a integrar las tablas de datos jQuery en la aplicación vue js.

No solo, sino que también lo ayuda a mostrar datos dinámicamente en una tabla de datos usando el servidor Axios y JSON y una API REST en la aplicación Vue js usando el notable paquete de tabla de datos jQuery.

Fuente: https://www.positronx.io/vue-js-dynamic-jquery-datatables-tutorial-example/

#vuej #jquery #datatable #json #restapi 

Cómo Integrar JQuery DataTables En La Aplicación Vue 2