implementation 'org.springframework.boot:spring-boot-starter-graphql'
implementation 'com.graphql-java-kickstart:playground-spring-boot-starter:5.10.0'
spring:
graphql:
graphiql:
enabled: true # graphiql을 통해 테스트 가능 여부 (localhost:8080/graphiql)
printer:
enabled: true # show-sql와 같이 graphql 콘솔에 쿼리 출력
graphql을 사용하기 전에 schema를 설정해줘야 하는데, src/main/resources/graphql
하위 폴더에 schema.graphqls
파일을 만들고 거기에 스키마를 설정해놓으면 spring-boot-graphql 이 컨트롤러에서 받은 요청을 자동으로 매핑시킨다.
type Member{
id: ID!
name: String!
age: Int!
}
type Query{
getMember(id: ID!): Member
getMembers: [Member]
}
type Mutation{
save(name: String!, age: Int!): Member
}
Query
와 Mutation
의 schema는 Controller
로 매핑된다 따라서 컨트롤러에 정의된 메서드의 시그니처와 다르면(인자나 메서드명이 다르면) 매핑되지 않는다.@GraphQlRepository
어노테이션을 통해 간단하게 사용할 수 있다@GraphQlRepository
public interface MemberRepository extends JpaRepository<Member, Long> {
}
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private int age;
}
@Controller
@RequiredArgsConstructor
public class MemberController {
private final MemberRepository memberRepository;
@QueryMapping
public Member getMember(@Argument Long id){
return memberRepository.findById(id).get();
}
@QueryMapping
public List<Member> getMembers(){
return memberRepository.findAll();
}
@MutationMapping
public Member save(@Argument Long id, @Argument String name, @Argument int age){
Member member = Member.builder()
.name(name)
.age(age)
.build();
return memberRepository.save(member);
}
}
Controller
단이다.localhost:8080/graphiql
를 통해 graphiql를 사용해서 테스트를 진행할 수 있다
grapqhl을 사용하면 다른 객체를 query로 묶어서 가져올 수 있다
@oController
@RequiredArgsConstructor
public class Controller {
@SchemaMapping
public List<Car> car(Member member){
return carRepository.findByMemberId(member.getId().intValue());;
}
}
type Member{
id: ID!
name: String!
age: Int!
car: [Car]
}
type Car{
id: ID!
name: String!
memberId: Int!
}
@SchemaMapping
어노테이션을 사용하면 Member 조회 시에 자동으로 메서드가 매핑된다
주의해야 하는 점은 schema
의 field 명과 메서드 명이 동일해야 메서드로 매핑된다는 점이다
아래와 같은 경우 매핑되지 않는다
@oController
@RequiredArgsConstructor
public class Controller {
@SchemaMapping
public List<Car> car(Member member){
return carRepository.findByMemberId(member.getId().intValue());;
}
}
type Member{
id: ID!
name: String!
age: Int!
mmCar: [Car]
}
정상적인 경우 다음과 같이 한번에 데이터를 받아올 수 있다