目录
一、创建一个SpringBoot项目,并导入下方依赖
二、配置 application.properties文件
三、在resources下创建graphql目录,并在graphql下创建三个.graphql文件(acomm.graphql , classes.graphql , student.graphql)
acomm.graphql 中的内容
classes.graphql 中的内容
student.graphql中的内容
四、 创建类
1. 创建与下方图片相同的层级目录
2. Classes类、Student类和SexEnum类中代码
3. PersonFieldResolver类中代码
4. UserInput类和PersonInput类中的代码
5. ClassesMutationResolver类、StudentMutationResolver类中的代码
6. ClassesQueryResolver类、StudentQueryResolver类中代码
7.LocalDateTimeScalar类中的代码
8.AppRunner类中的代码
五、使用浏览器打开 http://127.0.0.1:8080/playground 网站
1. 查询
2. 创建
代码地址
自己记录的一些笔记,内容如有不对请指正
com.graphql-java-kickstart
graphql-spring-boot-starter
11.0.0
com.graphql-java-kickstart
playground-spring-boot-starter
7.1.0
runtime
cn.hutool
hutool-all
5.5.9
org.projectlombok
lombok
true
spring.main.banner-mode=off
server.compression.enabled=true
# graphql文件位置,默认情况下会扫描 classpath 下所有的 graphqls 或 graphql 后缀文件。
graphql.tools.schema-location-pattern=./graphql/*.graphql*
#设置http://127.0.0.1:8080/playground网页的颜色,dark为黑色,light为白色
graphql.playground.settings.editor.theme=light
acomm.graphql 中的内容
# Scalar 是一种标量数据类型,表示单个原始值。GraphQL 内置了几种标量类型,包括 Int、Float、String、Boolean、ID 等,客户端和服务端可以使用这些标量类型来定义和约束数据模型。 # 除了内置的标量类型外,GraphQL 还允许用户自定义标量类型,以满足业务需求。例如,如果我们需要表示日期时间类型的数据,可以通过自定义 Scalar 类型来实现。 # 自定义 Scalar 类型需要指定以下三个方法: # 在 GraphQL 中,要自定义标量类型,需要实现 GraphQLScalarType 接口。 # parseLiteral:用来读取从客户端传递的常量值,例如在查询中直接写入的字符串或数字等。 # parseValue:用来读取从客户端传递的变量值 # serialize:将类型的值序列化为字符串表示形式,用于输出到客户端 scalar LocalDateTime # Schema 是一个重要的概念,用于定义数据在服务端如何组织和暴露给客户端 # Schema 描述了所有可用的数据类型(Data Type)、查询(Query)和变更(Mutation)以及订阅(Subscription),并指定它们之间的关联关系 schema { # query query: Query # mutation mutation: Mutation } type Query { # ! 表示不能为空,[]表示为链表或数组 } type Mutation{ } #定义一个枚举类 # Sex 可为参数,也可为返回值 enum SexEnum{ MALE FEMALE }
classes.graphql 中的内容
# extend 表示继承,继续对 acomm.qraphql 中 Query 的编写 extend type Query{ classesQuery:Classes classesQueryList:[Classes!] classesQueryBy(id:String!):Classes } # extend 表示继承,继续对 acomm.qraphql 中 Mutation 的编写 extend type Mutation { createClasses(input:ClassesInput):Classes } # input 表示ClassesInput只能作为为参数 # 且必须创建一个名字、参数都与这里定义相同的类 input ClassesInput{ name:String } # type 表示Classes不能作为为参数,可为返回值 # 且必须创建一个名字、参数都与这里定义相同的类 type Classes{ id:String name:String }
student.graphql中的内容
# ! 表示不能为空 # extend 表示继承,继续对 acommn.qraphql 中 Query 的编写 extend type Query{ studentQuery :Student studentQueryList:[Student!] studentQueryBy(id:String!): Student } # extend 表示继承,继续对 acommn.qraphql 中 Mutation 的编写 extend type Mutation{ createStudent(input:StudentInput):Student } # input 表示StudentInput只能作为为参数 # 且必须创建一个名字、参数都与这里定义相同的类 input StudentInput{ name:String sex:SexEnum birthday:LocalDateTime classesInput:ClassesInput } # type 表示Student不能作为为参数,可为返回值 # 且必须创建一个名字、参数都与这里定义相同的类 type Student { id:String name:String sex:SexEnum birthday:LocalDateTime classes:Classes }
1. 创建与下方图片相同的层级目录
个人习惯,可以不同
2. Classes类、Student类和SexEnum类中代码
@Data public class Student { private String id; private String name; private SexEnum sex; private LocalDateTime birthday; private Classes classes; }
@Data public class Student { private String id; private String name; private SexEnum sex; private LocalDateTime birthday; private Classes classes; }
@Getter public enum SexEnum { /** * 男 */ MALE("男"), /** * 女 */ FEMALE("女"); SexEnum(String sex) { this.sex = sex; } private final String sex; }
3. PersonFieldResolver类中代码
/** * 该类用于给 Person类 的 user 和 list 添加数据 * @author y */ @Component public class PersonFieldResolver implements GraphQLResolver
{ /** * 该方法名要与Person类中User的变量名相同,且参数类型必须是Person */ public User user(Person person){ return new User("1","wjy", Sex.MALE,"yqy"); } /** * 该方法名要与Person类中List 的变量名相同,且参数类型必须是Person */ public List list(Person person){ return Arrays.asList("e","f","g"); } }
4. ClassesInput类和StudentInput类中的代码
@Data public class ClassesInput { private String name; public Classes to() { Classes classes = new Classes(); classes.setId(UUID.fastUUID().toString()); classes.setName(name); return classes; } }
@Data public class StudentInput { private String name; private SexEnum sex; private LocalDateTime birthday; private ClassesInput classesInput; }
5. ClassesMutationResolver类、StudentMutationResolver类中的代码
@Component public class ClassesMutationResolver implements GraphQLMutationResolver { public Classes createClasses(ClassesInput input) { Classes classes = new Classes(); classes.setId(UUID.fastUUID().toString()); classes.setName("软件工程"); return classes; } }
@Component public class StudentMutationResolver implements GraphQLMutationResolver { public Student createStudent(StudentInput input) { Student student = new Student(); student.setId(UUID.fastUUID().toString()); student.setName("软件工程"); student.setSex(input.getSex()); student.setBirthday(input.getBirthday()); student.setClasses(input.getClassesInput().to()); return student; } }
@Component public class ClassesQueryResolver implements GraphQLQueryResolver { public Classes classesQuery() { Classes classes = new Classes(); classes.setId(UUID.fastUUID().toString()); classes.setName("软件工程"); return classes; } public List
classesQueryList() { List classesList = new ArrayList<>(); for (int i = 0; i < 10; i++) { Classes classes = new Classes(); classes.setId(UUID.fastUUID().toString()); classes.setName("软件工程 " + i); classesList.add(classes); } return classesList; } public Classes classesQueryBy(String id) { Classes classes = new Classes(); classes.setId(id); classes.setName("软件工程"); return classes; } } @Component public class StudentQueryResolver implements GraphQLQueryResolver { public Student studentQuery() { Student student = new Student(); student.setId(UUID.fastUUID().toString()); student.setName("wjy"); student.setSex(SexEnum.MALE); student.setBirthday(LocalDateTime.now()); return student; } public List
studentQueryList() { List students = new ArrayList<>(); for (int i = 0; i < 10; i++) { Student student = new Student(); student.setId(UUID.fastUUID().toString()); student.setName("wjy " + i); student.setSex(SexEnum.MALE); students.add(student); student.setBirthday(LocalDateTime.now()); } return students; } public Student studentQueryBy(String id) { Student student = new Student(); student.setId(id); student.setName("wjy"); student.setSex(SexEnum.MALE); student.setBirthday(LocalDateTime.now()); return student; } }
7.LocalDateTimeScalar类中的代码
@Configuration public class LocalDateTimeScalar { /** * NOTICE: 注意使用 秒级 时间戳 */ @Bean public GraphQLScalarType graphqlscalartype() { String localDateTimeStr = "LocalDateTime"; String description = "当地日期时间"; return GraphQLScalarType.newScalar() .name(localDateTimeStr) .description(description) .coercing(new LocalDateTimeCoercing()) .build(); } private static class LocalDateTimeCoercing implements Coercing
{ /** * 当后端向前端发送 LocalDateTime 类型数据时调用的方法,将 LocalDateTime 型的数据转换为 Long 型再传给前端 */ @Override public Long serialize(@NotNull Object o) throws CoercingSerializeException { if (o instanceof LocalDateTime) { return ((LocalDateTime) o).toEpochSecond(ZoneOffset.ofHours(8)); } else { throw new CoercingSerializeException("Unable to serialize " + o + " as LocalDateTime"); } } /** * parseValue用来读取从客户端传递的变量值 */ @NotNull @Override public LocalDateTime parseValue(@NotNull Object o) throws CoercingParseValueException { return parse(o); } /** * parseLiteral用来读取从客户端传递的常量值 */ @NotNull @Override public LocalDateTime parseLiteral(@NotNull Object o) throws CoercingParseLiteralException { return parse(o); } private LocalDateTime parse(Object o) { long time; System.out.println(o); if (o instanceof Long) { time = (Long) o; } else if (o instanceof String) { time = Long.parseLong((String) o); } else if (o instanceof StringValue) { time = Long.parseLong(((StringValue) o).getValue()); } else if (o instanceof IntValue) { time = ((IntValue) o).getValue().longValue(); } else { throw new CoercingParseValueException("Unable to parse value " + o + " as LocalDateTime"); } return LocalDateTime.ofEpochSecond(time, 0, ZoneOffset.ofHours(8)); } } }
8.AppRunner类中的代码
@Slf4j @Component public class AppRunner implements ApplicationRunner { @Override public void run(ApplicationArguments args) { try { ConfigurableEnvironment environment = IocUtil.get(ConfigurableEnvironment.class); String url = InetAddress.getLocalHost().getHostAddress(); String port = environment.getProperty("local.server.port"); log.info("graphql playground: http://{}:{}/playground", url, port); } catch (UnknownHostException e) { e.printStackTrace(); } } }