」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > Node.js 入門專案包括 GraphQL、Redis、JWT 和 Sequelize

Node.js 入門專案包括 GraphQL、Redis、JWT 和 Sequelize

發佈於2024-12-22
瀏覽:667

Node.js Starter Project dengan GraphQL, Redis, JWT, dan Sequelize

此模板提供了一个 Node.js 入门项目,已配置 GraphQL 用于 API,Redis 用于缓存和临时数据存储,JWT 用于身份验证和授权,Sequelize 用于 ORM连接到关系数据库,例如 PostgreSQL 或 MySQL。该项目具有模块化结构,可让您立即开发具有集成和可扩展功能的现代 Web 应用程序。

?项目概况

该项目旨在让使用 GraphQL API 更轻松地开发后端应用程序,该 API 使用 Redis 进行数据缓存,并使用 JWT 来保护 API。 Sequelize 用作 ORM 来促进与关系数据库的交互。此外,还有中间件可以更轻松地处理身份验证、验证和日志记录。

主要特点

  • GraphQL API实现更灵活、高效的查询和数据突变
  • JWT 身份验证 用于基于令牌的安全身份验证
  • Redis用于数据缓存和提高应用程序性能
  • Sequelize ORM用于关系数据库管理
  • 中间件用于集中授权和请求处理
  • 模块化且结构良好可扩展且更易于维护

?️ 使用的技术

  • Node.js:使用 JavaScript 构建服务器端应用程序的平台。了解更多
  • GraphQL:API 的查询语言,可实现高效、灵活的数据检索。了解更多
  • Redis:临时数据存储(内存中),通常用于缓存和消息代理。了解更多
  • JWT:安全且简单的基于令牌的身份验证技术。了解更多
  • Sequelize:Node.js 的 ORM,支持 PostgreSQL、MySQL 和其他关系数据库。了解更多

?设置和运行项目的步骤

1. 克隆存储库

首先,将此模板存储库克隆到本地计算机:

git clone https://gitlab.com/dioarafi1/graphify-api.git
cd graphify-api

如果您从头开始,请使用以下命令初始化一个新项目:

mkdir blog-api
cd blog-api
npm init -y

2. 安装依赖项

克隆存储库或创建新项目后,运行命令安装所需的依赖项:

yarn install

这将安装 package.json 文件中列出的所有依赖项。


3. 环境配置

在项目根目录下创建.env文件,为RedisJWTDatabase添加如下配置:

DATABASE_URL="postgresql://user:password@localhost:5432/mydatabase"
JWT_SECRET="your_jwt_secret_key"
REDIS_HOST="localhost"
REDIS_PORT="6379"

根据您的数据库配置更改用户、密码和 mydatabase。


4. 使用 Sequelize 准备数据库

如果没有配置数据库,请运行命令初始化Sequelize并创建模型:

yarn sequelize init

这将在您的项目中创建配置、模型和迁移目录结构。接下来,为应用程序创建必要的模型,例如 UserPost,并执行迁移以在数据库中创建表。

yarn sequelize db:migrate

确保数据库正在运行(例如使用 PostgreSQL 或 MySQL)。


5. 设置 GraphQL Server

安装 Apollo Server 和 GraphQL 的依赖项:

yarn add apollo-server graphql

之后,创建 GraphQL 服务器配置文件、架构和解析器。您可以通过以下方式配置 GraphQL 服务器:

src/服务器.ts

import { ApolloServer } from 'apollo-server-express';
import express from 'express';
import { typeDefs, resolvers } from './graphql';
import { authenticateJWT } from './middlewares/auth';
import { sequelize } from './config/database';

const app = express();

// Gunakan middleware JWT
app.use(authenticateJWT);

// Inisialisasi Apollo Server
const server = new ApolloServer({
  typeDefs,
  resolvers,
  context: ({ req }) => ({ user: req.user }),
});

server.applyMiddleware({ app });

const PORT = process.env.PORT || 4000;

app.listen(PORT, async () => {
  console.log(`Server running at http://localhost:${PORT}${server.graphqlPath}`);
  await sequelize.authenticate();
  console.log('Database connected');
});

src/graphql/schema.ts

定义查询和突变的 GraphQL 架构:

import { gql } from 'apollo-server-express';

export const typeDefs = gql`
  type User {
    id: ID!
    username: String!
  }

  type Post {
    id: ID!
    title: String!
    content: String!
    user: User!
  }

  type Query {
    posts: [Post]
    post(id: ID!): Post
    users: [User]
  }

  type Mutation {
    createPost(title: String!, content: String!): Post
    register(username: String!, password: String!): User
    login(username: String!, password: String!): String # JWT token
  }
`;

src/graphql/resolvers.ts

为查询和突变实现解析器:

import { Post, User } from '../models';
import jwt from 'jsonwebtoken';
import bcrypt from 'bcryptjs';

export const resolvers = {
  Query: {
    posts: () => Post.findAll(),
    post: (_, { id }) => Post.findByPk(id),
    users: () => User.findAll(),
  },
  Mutation: {
    createPost: async (_, { title, content }, { user }) => {
      if (!user) throw new Error('Authentication required');
      const post = await Post.create({ title, content, userId: user.id });
      return post;
    },
    register: async (_, { username, password }) => {
      const hashedPassword = await bcrypt.hash(password, 10);
      const user = await User.create({ username, password: hashedPassword });
      return user;
    },
    login: async (_, { username, password }) => {
      const user = await User.findOne({ where: { username } });
      if (!user) throw new Error('User not found');

      const match = await bcrypt.compare(password, user.password);
      if (!match) throw new Error('Invalid password');

      const token = jwt.sign({ userId: user.id }, process.env.JWT_SECRET!, { expiresIn: '1h' });
      return token;
    },
  },
};

6. 运行开发服务器

要使用hot-reload在开发环境中运行服务器,请使用以下命令:

yarn dev

服务器将在http://localhost:4000运行,您可以访问GraphQL Playground来测试API查询和突变。


?项目目录结构

此项目目录结构旨在分隔应用程序的不同部分,使其更加模块化且易于维护:

/myapp
├── src
│   ├── middlewares      # Berisi middleware untuk otentikasi (JWT), caching (Redis), dan validasi
│   ├── routes           # Definisi endpoint API dan resolver GraphQL
│   ├── services         # Logika bisnis utama dan pengolahan data
│   ├── app.ts           # File utama untuk inisialisasi aplikasi dan middleware
│   ├── graphql          # Menyimpan konfigurasi GraphQL, schema, dan resolvers
│   ├── models           # Model Sequelize untuk mengelola database relasional
│   ├── config           # File konfigurasi global untuk Redis, JWT, database, dll
│   ├── index.ts         # Entry point aplikasi, menginisialisasi server dan middleware
│   ├── resolvers        # Berisi resolver GraphQL untuk query dan mutasi
│   ├── server.ts        # File untuk setup Apollo Server dan konfigurasi GraphQL
│   ├── schema           # Definisi schema GraphQL
│   ├── types            # TypeScript types dan interfaces untuk GraphQL dan lainnya
│   └── utils            # Berisi helper dan fungsi utility
├──

 .env                 # File konfigurasi environment (Redis, JWT Secret, Database URL)
├── package.json         # Metadata proyek dan dependensi
└── tsconfig.json        # Konfigurasi TypeScript

?部署

要准备生产项目,请使用以下命令将 TypeScript 构建为 JavaScript:

yarn build

输出将位于 dist/ 文件夹中并准备好部署到生产服务器。

为云平台做准备

此项目可以部署到 HerokuAWSDigitalOcean 等平台,步骤如下:

  1. 将代码推送到 Git 存储库(GitHub、GitLab 或其他)。
  2. 在所选云平台(Redis、JWT Secret、URL 数据库)上设置环境变量
  3. 使用云平台的命令或集成部署项目

?资源

  • GraphQL 文档
  • Redis 文档
  • 智威汤逊文档
  • 续集文档

按照上述步骤,您现在可以使用 RedisJWTSequelize 运行和开发 GraphQL API 应用程序。

版本聲明 本文轉載於:https://dev.to/dioarafi/nodejs-starter-project-dengan-graphql-redis-jwt-dan-sequelize-2l3i?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 如何從PHP中的Unicode字符串中有效地產生對URL友好的sl。
    如何從PHP中的Unicode字符串中有效地產生對URL友好的sl。
    為有效的slug生成首先,該函數用指定的分隔符替換所有非字母或數字字符。此步驟可確保slug遵守URL慣例。隨後,它採用ICONV函數將文本簡化為us-ascii兼容格式,從而允許更廣泛的字符集合兼容性。 接下來,該函數使用正則表達式刪除了不需要的字符,例如特殊字符和空格。此步驟可確保slug僅包...
    程式設計 發佈於2025-07-19
  • 為什麼使用Firefox後退按鈕時JavaScript執行停止?
    為什麼使用Firefox後退按鈕時JavaScript執行停止?
    導航歷史記錄問題:JavaScript使用Firefox Back Back 此行為是由瀏覽器緩存JavaScript資源引起的。要解決此問題並確保在後續頁面訪問中執行腳本,Firefox用戶應設置一個空功能。 警報'); }; alert('inline Alert')...
    程式設計 發佈於2025-07-19
  • PHP未來:適應與創新
    PHP未來:適應與創新
    PHP的未來將通過適應新技術趨勢和引入創新特性來實現:1)適應云計算、容器化和微服務架構,支持Docker和Kubernetes;2)引入JIT編譯器和枚舉類型,提升性能和數據處理效率;3)持續優化性能和推廣最佳實踐。 引言在編程世界中,PHP一直是網頁開發的中流砥柱。作為一個從1994年就開始發展...
    程式設計 發佈於2025-07-19
  • 反射動態實現Go接口用於RPC方法探索
    反射動態實現Go接口用於RPC方法探索
    在GO 使用反射來實現定義RPC式方法的界面。例如,考慮一個接口,例如:鍵入myService接口{ 登錄(用戶名,密碼字符串)(sessionId int,錯誤錯誤) helloworld(sessionid int)(hi String,錯誤錯誤) } 替代方案而不是依靠反射...
    程式設計 發佈於2025-07-19
  • 解決MySQL插入Emoji時出現的\\"字符串值錯誤\\"異常
    解決MySQL插入Emoji時出現的\\"字符串值錯誤\\"異常
    Resolving Incorrect String Value Exception When Inserting EmojiWhen attempting to insert a string containing emoji characters into a MySQL database us...
    程式設計 發佈於2025-07-19
  • 如何在GO編譯器中自定義編譯優化?
    如何在GO編譯器中自定義編譯優化?
    在GO編譯器中自定義編譯優化 GO中的默認編譯過程遵循特定的優化策略。 However, users may need to adjust these optimizations for specific requirements.Optimization Control in Go Compi...
    程式設計 發佈於2025-07-19
  • 如何將多種用戶類型(學生,老師和管理員)重定向到Firebase應用中的各自活動?
    如何將多種用戶類型(學生,老師和管理員)重定向到Firebase應用中的各自活動?
    Red: How to Redirect Multiple User Types to Respective ActivitiesUnderstanding the ProblemIn a Firebase-based voting app with three distinct user type...
    程式設計 發佈於2025-07-19
  • 如何同步迭代並從PHP中的兩個等級陣列打印值?
    如何同步迭代並從PHP中的兩個等級陣列打印值?
    同步的迭代和打印值來自相同大小的兩個數組使用兩個數組相等大小的selectbox時,一個包含country代碼的數組,另一個包含鄉村代碼,另一個包含其相應名稱的數組,可能會因不當提供了exply for for for the uncore for the forsion for for ytry...
    程式設計 發佈於2025-07-19
  • 在Java中使用for-to-loop和迭代器進行收集遍歷之間是否存在性能差異?
    在Java中使用for-to-loop和迭代器進行收集遍歷之間是否存在性能差異?
    For Each Loop vs. Iterator: Efficiency in Collection TraversalIntroductionWhen traversing a collection in Java, the choice arises between using a for-...
    程式設計 發佈於2025-07-19
  • 在Python中如何創建動態變量?
    在Python中如何創建動態變量?
    在Python 中,動態創建變量的功能可以是一種強大的工具,尤其是在使用複雜的數據結構或算法時,Dynamic Variable Creation的動態變量創建。 Python提供了幾種創造性的方法來實現這一目標。 利用dictionaries 一種有效的方法是利用字典。字典允許您動態創建密鑰並...
    程式設計 發佈於2025-07-19
  • 為什麼不````''{margin:0; }`始終刪除CSS中的最高邊距?
    為什麼不````''{margin:0; }`始終刪除CSS中的最高邊距?
    在CSS 問題:不正確的代碼: 全球範圍將所有餘量重置為零,如提供的代碼所建議的,可能會導致意外的副作用。解決特定的保證金問題是更建議的。 例如,在提供的示例中,將以下代碼添加到CSS中,將解決餘量問題: body H1 { 保證金頂:-40px; } 此方法更精確,避免了由全局保證金重置...
    程式設計 發佈於2025-07-19
  • PHP陣列鍵值異常:了解07和08的好奇情況
    PHP陣列鍵值異常:了解07和08的好奇情況
    PHP數組鍵值問題,使用07&08 在給定數月的數組中,鍵值07和08呈現令人困惑的行為時,就會出現一個不尋常的問題。運行print_r($月)返回意外結果:鍵“ 07”丟失,而鍵“ 08”分配給了9月的值。 此問題源於PHP對領先零的解釋。當一個數字帶有0(例如07或08)的前綴時,PHP將...
    程式設計 發佈於2025-07-19
  • 如何從PHP中的數組中提取隨機元素?
    如何從PHP中的數組中提取隨機元素?
    從陣列中的隨機選擇,可以輕鬆從數組中獲取隨機項目。考慮以下數組:; 從此數組中檢索一個隨機項目,利用array_rand( array_rand()函數從數組返回一個隨機鍵。通過將$項目數組索引使用此鍵,我們可以從數組中訪問一個隨機元素。這種方法為選擇隨機項目提供了一種直接且可靠的方法。
    程式設計 發佈於2025-07-19
  • 切換到MySQLi後CodeIgniter連接MySQL數據庫失敗原因
    切換到MySQLi後CodeIgniter連接MySQL數據庫失敗原因
    Unable to Connect to MySQL Database: Troubleshooting Error MessageWhen attempting to switch from the MySQL driver to the MySQLi driver in CodeIgniter,...
    程式設計 發佈於2025-07-19
  • C++20 Consteval函數中模板參數能否依賴於函數參數?
    C++20 Consteval函數中模板參數能否依賴於函數參數?
    [ consteval函數和模板參數依賴於函數參數在C 17中,模板參數不能依賴一個函數參數,因為編譯器仍然需要對非contexexpr futcoriations contim at contexpr function進行評估。 compile time。 C 20引入恆定函數,必須在編譯時進...
    程式設計 發佈於2025-07-19

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3