
Motivation
public record Customer(
String name,
String email,
Address address,
List<Order> orders,
String avatarUrl) { }
- /home
- name, avatarUrl
- /orders
- orders
- /profile
- alles
Lösungen
/customers/{id} lädt alles
- Extratraffic (mobile!)
- 3 Endpoints
- Skalierung 😕
- Backend restricted Frontend
GraphQL
{
customer(id: 42) {
name
avatarUrl
}
}
- Client spezifiziert zu liefernde Daten
- Server schickt nur Benötigtes
- 2015 von Meta veröffentlicht
magic--
{
students {
id
name
}
}
POST http://localhost:8080/graphql
Content-Type: application/json
{
"query": "{students {id name} }"
}
Schema
type Student {
id: String
name : String!
schoolClass: SchoolClass!
}
type SchoolClass {
title: String!
students: [Student!]!
}
type Query {
students: [Student!]!
withClass(schoolClass: String!): [Student!]!
student(id: String!): Student
}
Queries
query {
students {
id
name
}
}
{
withClass(schoolClass: "5AHIF") {
id
name
schoolClass{
title
}
}
}
Mutations
type Mutation {
createStudent(student: StudentInput!): Student
}
input StudentInput {
name : String!
classTitle: String!
}
mutation {
createStudent(student: { name: "new", classTitle: "5AHIF" }) {
id
}
}
Controller
type Query {
students: [Student!]!
student(id: String!): Student
}
type Mutation {
createStudent(student: StudentInput!): Student
}
@Controller
public class GraphQLController {
@QueryMapping
public List<Student> students() { ... }
@QueryMapping
public Student student(@Argument String id) { ... }
@MutationMapping
public Student createStudent(
@Valid @Argument("student") StudentInput studentInput) { ... }
}
Error Handling
@Component
public class ExceptionResolver extends DataFetcherExceptionResolverAdapter {
@Override
protected List<GraphQLError> resolveToMultipleErrors(Throwable ex, DataFetchingEnvironment env) {
var errors = new ArrayList<GraphQLError>();
if (ex instanceof NoSuchElementException)
errors.add(buildGraphQLError(ErrorType.NOT_FOUND, ex, env));
if (ex instanceof BindException)
errors.add(buildGraphQLError(ErrorType.BAD_REQUEST, ex, env));
return errors;
}
private static GraphQLError buildGraphQLError(ErrorType type, Throwable ex, DataFetchingEnvironment env) {
return GraphqlErrorBuilder.newError()
.errorType(type)
.message(ex.getMessage())
.path(env.getExecutionStepInfo().getPath())
.location(env.getField().getSourceLocation())
.build();
}
}