React + nestjs + Graphql 学习记录

本文介绍了作者在学习GraphQL后,决定结合React和NestJS搭建一个全栈Demo的过程。选择了React作为前端框架,因为它符合公司的技术栈且作者喜欢其JSX风格。NestJS作为后端框架,因其完整的架构和对typescript的支持。文章详细讲述了从初始化项目、设置GraphQL模块、创建用户模块,到使用ApolloClient在React中发送GraphQL查询的步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

最近学习了一下 graphql ,想结合之前的技术栈,Reactnestjs 来做了全栈的小 demo ,总觉得学习东西不做笔记或者记录,很容易就忘记,虽然做了笔记也很容易忘记,但至少到时候回头看的时候,方便复习吗?至于为啥是选择 React,因为公司的技术栈是 React,我个人也很喜欢 jsx 这种风格,hooks 出来之后,写起来更爽了,纯纯的个人感情。而选 nestjs 的原因是相比其他的框架 (expresskoa)来说,我觉得他的架构更完整一些,自带支持 typescriptes6 语法,如果要用 express 或者 koa 去搭这个架子,那就有得折腾了。而且 nestjs 有很多新的编程概念(当然是相对我来说是新的),AOP呀,依赖注入和控制反转之类的,这些应该部分前端的小伙伴都是比较陌生的概念吧。当然也有学习负担,多接触些新的东西,不容易感觉自己在原地踏步。话不多说,撸起袖子,写代码吧。

服务端

  1. 脚手架创建项目
npm i -g @nestjs/cli
nest new graphql-demo
  1. 目录整理

删除 app.service.tsapp.controller.tsapp.controller.spec.tssrc 目录 就剩下 main.tsapp.module.ts 就行

  1. 安装 graphql 相关依赖
npm i @nestjs/graphql @nestjs/apollo graphql apollo-server-express
  1. 导入 GraphQLModule 到 app
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { join } from 'path';

@Module({
  imports: [
  	// 注入到app里头
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      // code-first: 自动生成 gql 文件
      autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
    }),
  ],
  controllers: [],
  providers: [],
})
export class AppModule {}
  1. 创建用户模块
nest g mo users

执行完上面的脚本,就会生成一个 user目录, 里头有一个文件 user.module.ts,我们在创建一个 use.resolver.ts

import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
import { UserEntity } from './user.entity';
import { CreateUserInputDto } from './dtos/create-user.dot';

@Resolver(() => UserEntity)
export class UserResolver {
  // 返回字符串
  @Query(() => String)
  getHello(): string {
    return 'hi, nest js';
  }

  // 这里可以根据 service,配合 typeorm 来返回数据库数据
  @Query(() => [UserEntity])
  getUserList(@Args('admin') admin: boolean): UserEntity[] {
    if (admin) {
      return [];
    }
    return [];
  }
  // 提交数据,主要传递参数的方式
  @Mutation(() => Boolean)
  createUser(@Args('user') createUserInput: CreateUserInputDto): boolean {
    console.log(createUserInput);
    return true;
  }
}

上面的代码还需要创建两个文件

  1. user.entity.ts :是用来描述 User 数据库模型的,简单的说就是 User 在数据库中有哪些数据,配合 Orm 可以实现自动创建表
  2. create-user.dot: 这个是用来校验数据的
  1. 创建 entity 和 dtos
// entity.ts
import { Field, ObjectType } from '@nestjs/graphql';

@ObjectType()
export class UserEntity {
  @Field(() => String)
  name: string;

  @Field(() => Boolean)
  admin: boolean;

  @Field(() => String)
  email: string;

  @Field(() => String)
  dep: string;

  @Field(() => String)
  password: string;
}
// create-user.dot.ts
import { Field, InputType } from '@nestjs/graphql';
import { IsBoolean, IsString, IsEmail, Length, IsNotEmpty } from 'class-validator';

@InputType()
export class CreateUserInputDto {
  @Field(() => String)
  @IsString()
  @IsNotEmpty()
  name: string;

  @Field(() => Boolean)
  @IsBoolean()
  admin: boolean;

  @Field(() => String)
  @IsEmail()
  email: string;

  @Field(() => String)
  @IsString()
  dep: string;

  @Field(() => String)
  @IsString()
  @Length(6, 32)
  password: string;
}
  1. 开启全局校验
npm i class-transformer class-validator

main.ts 中使用 useGlobalPipes

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ValidationPipe } from '@nestjs/common';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  // 如果不写这一句,dtos 那里的校验是不会生效的
  app.useGlobalPipes(new ValidationPipe());
  // 这个是访问的端口
  await app.listen(4000);
}
bootstrap();

目录结构大致是这样的
在这里插入图片描述
后面接 orm 和 数据的部分就不添加了,本质上和 graphql 也没啥关系

  1. 访问 ://localhost:4000/graphql
    在这里插入图片描述
    右侧可以查看文档和 schema
    还有就是自动生成的这个 schema.gql 文件可以给前端作为类似接口的文档的作用来使用,不过做这个,好像都是前端后端一起写的
    在这里插入图片描述

客户端

  1. create-react-app

我们就用最简单的方式创建项目吧,直接使用 Create-react-app,这里就不用 typescript 了,方便一点,我是参照 Apollo Client 文档 来的。

  1. 安装 apollo/clientgraphql
npm install @apollo/client graphql
  1. 初始化 ApolloClient
// 在 `src/index.js` 中做初始化,就添加这一句导入
import { ApolloClient, InMemoryCache, ApolloProvider } from '@apollo/client'
// react 相关的,和 graphql 无关,初始化就有的
import React from 'react'
import ReactDOM from 'react-dom/client'
import './index.css'
import App from './App'

// 做初始化
const client = new ApolloClient({
  // 我们自己的后端地址
  uri: 'http://localhost:4000/graphql',
  cache: new InMemoryCache(),
})

const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
  <React.StrictMode>
    <ApolloProvider client={client}>
      <App />
    </ApolloProvider>
  </React.StrictMode>
)
  1. 发送请求,查询数据
// 查询数据用 useQuery,提交数据用 useMutation
import { gql, useQuery } from '@apollo/client'
import logo from './logo.svg'
import './App.css'

// 这个就是查询 graphql 语句
const GET_HELLO_STRING = gql`
  query GetHelloString {
    getHello
  }
`

function App() {
  const { loading, error, data } = useQuery(GET_HELLO_STRING)

  if (error) {
    return <h1>Error happened</h1>
  }

  if (!loading && data) {
    console.log(data)
  }

  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
      </header>
    </div>
  )
}

export default App
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值