GraphQL Mutation中能否自动生成UUID?实现方案咨询
UUID生成端选择
优先选择服务端生成,原因如下:
- 避免客户端生成的不可靠问题:客户端生成UUID存在重复、被恶意篡改、逻辑异常导致格式错误的风险,服务端生成可以完全把控生成规则和唯一性
- 减少客户端逻辑耦合:客户端不需要关心主键生成规则,后续你要调整主键类型、生成规则时不需要同步修改多端代码
- 可复用数据库原生能力:Postgres内置了
uuid-ossp扩展,提供uuid_generate_v4()等高可靠性的UUID生成函数,生成的UUID唯一性远高于大多数客户端自行实现的逻辑
服务端层级放置建议
根据你使用的type-graphql+Postgres技术栈,分两种优先级选择:
- 优先放在Entity层(推荐)
你大概率搭配了TypeORM/MikroORM这类ORM框架使用,直接在Entity的主键字段上配置自动生成规则即可,不需要手动编写业务代码。
以TypeORM为例,配置示例:
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm'; import { ObjectType, Field } from 'type-graphql'; @ObjectType() @Entity() export class Click { @Field() @PrimaryGeneratedColumn('uuid') // 直接配置UUID自动生成,插入数据时ORM会自动处理 id: string; @Field() @Column() clickId: string; // 其余字段省略 }
这种方式不需要手动赋值,插入数据时ORM会自动调用数据库能力生成UUID,效率最高、代码量最少。
- 次选放在Service层
如果你没有用ORM的自动生成能力,就放在业务逻辑对应的Service层,在执行数据库插入操作前生成UUID赋值给对应字段即可。
示例代码:
// Service层代码 import { v4 as uuidv4 } from 'uuid'; @Service() export class ClickService { async createClick(data: ClickInput) { // 生成UUID赋值 const clickData = { ...data, id: uuidv4() }; // 执行数据库插入逻辑 return this.clickRepository.save(clickData); } }
注:使用前需要安装uuid和对应类型依赖:npm install uuid @types/uuid
不要把UUID生成逻辑放在Controller层,Controller层只负责参数校验、请求转发、返回结果封装,不应该包含具体业务逻辑。
配套调整建议
你现在的请求参数里主动传了空的id字段,建议直接把ClickInput类型里的id字段移除,不需要客户端传递该参数,服务端生成完成后会在返回值里把id返回给客户端即可。
你提供的Apollo Sandbox截图如下:
内容的提问来源于stack exchange,提问作者Peter Jaffray
相关产品推荐
相关产品推荐

