GraphQL、sequelize-typescript 、Apollo Server 4 实例

news/2024/10/5 14:09:08

新建项目文件夹

$ mkdir demo
$ cd demo

初始化TypeScript配置

$ npx tsc --init

安装 Sequelize Sequelize-cli

$ npm install --save-dev @types/node @types/validator
$ npm install sequelize reflect-metadata sequelize-typescript
$ npm install --save-dev ts-node @types/express @types/node @types/sequelize

调整部分TypeScript配置

$ vi tsconfig.json

  "target": "es2022", "experimentalDecorators": true,  "emitDecoratorMetadata": true"useDefineForClassFields": false,"module": "es2022", "moduleResolution": "node", "baseUrl": "./src","allowJs": true, "allowSyntheticDefaultImports": true,"skipLibCheck": true,

使用一个sequelize配置文件,并进行sequelize初始化

$ vi .sequelizerc

// .sequelizerc
const path = require('path');module.exports = {config: path.resolve('src/database', 'sequelize.config.js'),'models-path': path.resolve('src/database', 'models'),'seeders-path': path.resolve('src/database', 'seeders'),'migrations-path': path.resolve('src/database', 'migrations'),
};

$ npx sequelize init

修改sequelize生成的数据库配置信息,使用sqlite,以及项目目录结构

$ vi src/database/sequelize.config.js --> .cjs

require('ts-node/register');module.exports = {env: 'development',dialect: 'sqlite',storage: './database.sqlite'
};

生成User信息model

$ npx sequelize-cli model:generate --name User --attributes firstname:string,lastname:string,email:string,password:string,memo:string
会创建两个文件

  • models/user.js
  • migrations/XXXXXXXXXXXXXX-create-user.js
    其中:XXXXXXXXXXXXXX- 是按时间戳生成的随机文件名

再生成一个美食Model

$ npx sequelize-cli model:generate --name Recipe --attributes userid:integer,title:string,ingredients:string,direction:string,memo:string
会创建两个文件

  • models/recipe.js
  • migrations/XXXXXXXXXXXXXX-create-recipe.js
    其中:XXXXXXXXXXXXXX- 是按时间戳生成的随机文件名

用Model产生的数据定义脚本在数据库建表

$ npx sequelize-cli db:migrate
执行后在demo目录下生成一个database.sqlite文件,存放User信息model、美食Model表结构,除指定字段信息外,还有sequelize附加的字段。

测试创建一个user

$ npx sequelize-cli seed:generate --name first-user
会创建在seeders目录

  • migratiseedersons/XXXXXXXXXXXXXX-first-user.js

执行测试文件在数据库User表增加用户信息

$ npx sequelize-cli db:seed:all

修改美食Model增加关联到User信息Model

// associate
Recipe.belongsTo(User, {as: 'user',foreignKey: {name: 'userid',allowNull: false,},foreignKeyConstraint: true,
});

修改User信息Model关联到美食Model

// associate
User.hasMany(Recipe,{as: 'recipes',foreignKey: {name: 'userid',allowNull: false,},foreignKeyConstraint: false,
})

创建sequelize数据连接文件

$ vi src/database/connect.ts

import {Sequelize} from 'sequelize-typescript';
import {Dialect} from 'sequelize';
import { DIALECT,DB_STORAGE,DB_DATABASE, DB_TIMEZONE, DB_HOST, DB_PORT, DB_PASSWORD, DB_USERNAME } from '../configs.js';const sqlite: Dialect = DIALECT as Dialect;
let opt = {dialect: sqlite,storage: DB_STORAGE,database: DB_DATABASE,username: DB_USERNAME,password: DB_PASSWORD,host: DB_HOST,port: DB_PORT,//timezone: DB_TIMEZONE,
}
const dataSource: Sequelize = new Sequelize(opt);export default dataSource;

安装 GraphQL Server 、 GraphQL以及其他组件包

$ npm install @apollo/server http express graphql graphql-tag bcryptjs

创建GraphQL的typeDefs文件

$ vi src/graphql/api/typeDefs.ts

import gql from 'graphql-tag';export const typeDefs = gql`#graphqltype User {id: Int!firstname: String!lastname: String!email: String!memo: Stringrecipes: [Recipe!]!}type Recipe {id: Int!title: String!ingredients: String!direction: String!memo: Stringuser: User!}type Query {user(id: Int!): UserallRecipes: [Recipe!]!recipe(id: Int!): RecipeallUsers: [User!]!}type Mutation {createUser(firstName: String!, lastName: String!, email: String!, password: String!, memo: String): UsercreateRecipe(userid: Int!title: String!ingredients: String!direction: String!memo: String): Recipe}
`;
export default typeDefs;

创建GraphQL的resolvers文件

$ vi src/graphql/api/resolvers.ts

import bcrypt from 'bcryptjs';import User from '../../database/models/user.model.js';
import Recipe from '../../database/models/recipe.model.js';export const resolvers = {Query: {user: async (root: any, args: { id: any; }, context: any, info: any) => {return User.findByPk(args.id);},allRecipes: async (parent: any, args: {}, context: any, info: any) => {return Recipe.findAll(info);},recipe: async (parent: any, args: { id: any; }, context: any, info: any) => {return Recipe.findByPk(args.id);},allUsers: async (parent: any, args: {}, context: any, info: any) => {return User.findAll();},},Mutation: {async createUser(parent: any,args: { firstname: any, lastname: any, email: any, password: any, memo: any },context: any,info: any) {return User.create({firstname: args.firstname,lastname: args.lastname,email: args.email,password: await bcrypt.hash(args.password, 10),memo: args.memo});},async createRecipe(parent: any,args: { userid: any, title: any, ingredients: any, direction: any, memo: any },context: any,info: any) {return Recipe.create({userid: args.userid,title: args.title,ingredients: args.ingredients,direction: args.direction,memo: args.memo});},},User: {async recipes(user: any) {return user.getRecipes();},},Recipe: {async user(recipe: any) {return recipe.getUser();},},};export default resolvers;

创建项目主文件,使用Apollo组件包

$ vi src/index.ts

import { ApolloServer } from '@apollo/server';
import { expressMiddleware } from '@apollo/server/express4';
import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer';import cors from 'cors';
import express from 'express';
import http from 'http';
import pkg from 'body-parser';
const { json } = pkg;import { typeDefs } from './graphql/api/typeDefs.js';
import { resolvers } from './graphql/api/resolvers.js';
import dbTables from './database/models/index.js';
import { SERVICE_PORT } from "./configs.js";const app = express();
// Our httpServer handles incoming requests to our Express app.
// Below, we tell Apollo Server to "drain" this httpServer,
// enabling our servers to shut down gracefully.
const httpServer = http.createServer(app);interface ContextValue  {dbTables?: typeof dbTables;
}const server = new ApolloServer({typeDefs,resolvers,plugins: [// Proper shutdown for the HTTP server.ApolloServerPluginDrainHttpServer({ httpServer }),],
});
await server.start();app.use(cors(),json(),expressMiddleware(server, {context: async ({ req }) => ({token: req.headers.token,dbTables: dbTables,}),}),
);const port = SERVICE_PORT || 4000;app.listen({ port: port }, () => console.log(`Server ready at http://localhost:${port}`))

修改 package.json, 增加编译和执行

$ vi package.json

  "scripts": {"build": "tsc","start": "nodemon --exec ts-node-esm build/index.js","dev": "node --loader ts-node/esm --no-warnings=ExperimentalWarning src/index.ts",},

最终来到运行和燕子示例

$ npm run build
$ npm run start
或者
$ npm run dev

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/67980.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

@ImportResource用法

用法 @ImportResource 注解用于导入 Spring的配置文件,让某个配置文件中的bean生效; SpringBoot里没有 Spring的配置文件,自己可以手动编写配置文件,但Spring Boot不能自动识别,此时需要在配置类中引入编写的配置文件 注意:这个配置文件生效需要放在 配置类上!! 举个例…

ROS基础入门——实操教程3C

合集 - Ubuntu强化学习合集(3)1.命令行gcc -v和g++ -v输出版本不一致09-272.crypt.h:No such file or directory 报错处理09-283.ROS基础入门——实操教程10-04收起 ROS基础入门——实操教程前言 本教程实操为主,少说书。可供参考的文档中详细的记录了ROS的实操和理论,只是过…

Linux_权限理解(详细PLUS)Gu

1.用户 Linux下有两种用户:超级用户(root)和普通用户; 超级用户:可以再linux系统下做任何事情,不受限制 普通用户:在linux下做有限的事情 超级用户的命令提示符是"#",普通用户的命令提示符是"$"超级用户:普通用户:2.用户切换 用户间切换: su + 用…

织梦php数据库配置文件

织梦CMS(DedeCMS)的数据库配置文件通常位于安装目录下的 include 文件夹中,具体文件名为 config.inc.php。这个文件包含了数据库连接的所有必要信息。下面详细说明如何配置这个文件。 步骤 1: 备份现有配置文件 在修改任何配置文件之前,最好先备份现有的配置文件,以防万一…

连接到数据库,你可以查看织梦CMS的相关表结构和数据

一旦连接到数据库,你可以查看织梦CMS的相关表结构和数据。 使用phpMyAdmin查看数据库表在phpMyAdmin中,选择你的织梦CMS数据库。 点击左侧的数据库名称,可以看到所有的表列表。 点击每个表,可以查看表结构和数据。使用MySQL命令行查看数据库表进入数据库后,运行以下命令查…

找到织梦CMS的数据库配置文件,以便了解数据库的具体连接信息

首先,找到织梦CMS的数据库配置文件,以便了解数据库的具体连接信息。 数据库配置文件路径织梦CMS安装目录假设织梦CMS安装在 /var/www/html 目录下。 数据库配置文件位于 include/config.inc.php。打开配置文件使用FTP工具或服务器上的文件管理器,打开织梦CMS安装目录下的 in…

织梦的数据库在哪,告诉我路径

织梦CMS(DedeCMS)的数据库并不是直接存储在文件系统中的某个特定路径下,而是存储在MySQL数据库服务器中。不过,织梦CMS的数据库配置文件和一些相关文件还是有固定的路径。以下是一些关键路径及其说明: 织梦CMS安装目录 假设你的织梦CMS安装在 /var/www/html 目录下,那么以…

vs code如何配置C/C++环境,实现完美运行.c/.cpp文件,以及终端乱码问题

环境配置 在 Visual Studio Code (VS Code) 中安装了 C/C++ Extension Pack 后,你可以通过以下步骤来运行 C++ 文件:安装编译器配置编译任务:在 VS Code 中,你可以创建一个编译任务来编译你的 C++ 文件。这通常通过创建一个 tasks.json 文件来完成。你可以通过以下步骤创建…