GraphQL
vs
Traditional REST API
Vladimir Dejanović
@VladimirD_42
amsterdamjug.com
ITShark.xyz
#DevoxxMA
#GraphQlVsRest
@VladimirD_42
Vladimir Dejanović
Let’s Meet
#GraphQlVsRest
@VladimirD_42
Vladimir Dejanović
Let’s Meet
#GraphQlVsRest
@VladimirD_42
Agenda
#GraphQlVsRest
@VladimirD_42
REST
Agenda
#GraphQlVsRest
@VladimirD_42
GraphQL
REST
Agenda
#GraphQlVsRest
@VladimirD_42
GraphQL
REST
Agenda
Questions
What is REST?
#GraphQlVsRest
#GraphQlVsRest
@VladimirD_42
REST
#GraphQlVsRest
@VladimirD_42
REST
Client-Server architecture
#GraphQlVsRest
@VladimirD_42
REST
Client-Server architecture
Statelessness
#GraphQlVsRest
@VladimirD_42
REST
Client-Server architecture
Statelessness
Cacheability
#GraphQlVsRest
@VladimirD_42
REST
Client-Server architecture
Statelessness
Cacheability
Layered system
#GraphQlVsRest
@VladimirD_42
REST
Client-Server architecture
Statelessness
Cacheability
Layered system
Code on Demand (Optional)
#GraphQlVsRest
@VladimirD_42
REST
Client-Server architecture
Statelessness
Cacheability
Layered system
Code on Demand (Optional)
Uniform Interface
#GraphQlVsRest
@VladimirD_42
REST
http://www.ics.uci.edu/~fielding/pubs/
dissertation/rest_arch_style.htm
#GraphQlVsRest
@VladimirD_42
Traditional REST API
#GraphQlVsRest
@VladimirD_42
Traditional REST API
#GraphQlVsRest
@VladimirD_42
Traditional REST API
#GraphQlVsRest
@VladimirD_42
Traditional REST API
#GraphQlVsRest
@VladimirD_42
Simple Blog
#GraphQlVsRest
@VladimirD_42
Simple Blog
Author
id
name
#GraphQlVsRest
@VladimirD_42
Simple Blog
Author
id
name
Post
id
title
body
authorId
#GraphQlVsRest
@VladimirD_42
Simple Blog
Author
id
name
Post
id
title
body
authorId
Comment
id
text
postId
authorId
#GraphQlVsRest
@VladimirD_42
Simple Blog
#GraphQlVsRest
@VladimirD_42
WARNING!!!!
Level of my real code is better ;)
This code was made intently for
demos, including errors and bad
code
Simple Blog
#GraphQlVsRest
@VladimirD_42
Let us Look at some code :D
Simple Blog
#GraphQlVsRest
@VladimirD_42
@Data
@Document(collection="authors")
public class Author {
@Id
private final String id;
private final String name;
}
Simple Blog
#GraphQlVsRest
@VladimirD_42
@Data
@Document(collection="authors")
public class Author {
@Id
private final String id;
private final String name;
}
Simple Blog
#GraphQlVsRest
@VladimirD_42
@Data
@Document(collection="authors")
public class Author {
@Id
private final String id;
private final String name;
}
Simple Blog
#GraphQlVsRest
@VladimirD_42
@Data
@Document(collection="authors")
public class Author {
@Id
private final String id;
private final String name;
}
Simple Blog
#GraphQlVsRest
@VladimirD_42
@Data
@Document(collection="authors")
public class Author {
@Id
private final String id;
private final String name;
}
Simple Blog
#GraphQlVsRest
@VladimirD_42
public interface AuthorRepository extends
MongoRepository<Author, String>
{}
Simple Blog
#GraphQlVsRest
@VladimirD_42
public interface AuthorRepository extends
MongoRepository<Author, String>
{}
Simple Blog
#GraphQlVsRest
@VladimirD_42
public interface AuthorRepository extends
MongoRepository<Author, String>
{}
Simple Blog
#GraphQlVsRest
@VladimirD_42
@RestControllerpublic
class SimpleRestController {
@Autowired
AuthorRepository authRepo;
@RequestMapping(path="/authors")
public List<Author> getAllAuthors() {
return authRepo.findAll(); }
@RequestMapping(path="/authors/{id}")
public Author getAuthorById(
@PathVariable String id) {
return authRepo.findOne(id);}
. . . . . .
Simple Blog
#GraphQlVsRest
@VladimirD_42
@RestControllerpublic
class SimpleRestController {
@Autowired
AuthorRepository authRepo;
@RequestMapping(path="/authors")
public List<Author> getAllAuthors() {
return authRepo.findAll(); }
@RequestMapping(path="/authors/{id}")
public Author getAuthorById(
@PathVariable String id) {
return authRepo.findOne(id);}
. . . . . .
Simple Blog
#GraphQlVsRest
@VladimirD_42
@RestControllerpublic
class SimpleRestController {
@Autowired
AuthorRepository authRepo;
@RequestMapping(path="/authors")
public List<Author> getAllAuthors() {
return authRepo.findAll(); }
@RequestMapping(path="/authors/{id}")
public Author getAuthorById(
@PathVariable String id) {
return authRepo.findOne(id);}
. . . . . .
Simple Blog
#GraphQlVsRest
@VladimirD_42
@RestControllerpublic
class SimpleRestController {
@Autowired
AuthorRepository authRepo;
@RequestMapping(path="/authors")
public List<Author> getAllAuthors() {
return authRepo.findAll(); }
@RequestMapping(path="/authors/{id}")
public Author getAuthorById(
@PathVariable String id) {
return authRepo.findOne(id);}
. . . . . .
Simple Blog
#GraphQlVsRest
@VladimirD_42
@RestControllerpublic
class SimpleRestController {
@Autowired
AuthorRepository authRepo;
@RequestMapping(path="/authors")
public List<Author> getAllAuthors() {
return authRepo.findAll(); }
@RequestMapping(path="/authors/{id}")
public Author getAuthorById(
@PathVariable String id) {
return authRepo.findOne(id);}
. . . . . .
Simple Blog
#GraphQlVsRest
@VladimirD_42
$ curl http://localhost:8080/authors | json_pp
[
{
"id" : "59f4c0f37718af0b1e001071",
"name" : "Ed Wong”
},
{
"id" : "59f4c1687718af0b1e001073",
"name" : "Son Goku”
}
]
Simple Blog
#GraphQlVsRest
@VladimirD_42
$ curl http://localhost:8080/authors | json_pp
[
{
"id" : "59f4c0f37718af0b1e001071",
"name" : "Ed Wong”
},
{
"id" : "59f4c1687718af0b1e001073",
"name" : "Son Goku”
}
]
Simple Blog
#GraphQlVsRest
@VladimirD_42
Code for Post and Comment similar
to code for Author
Simple Blog
#GraphQlVsRest
@VladimirD_42
$ curl http://localhost:8080/posts | json_pp
[
{
"body" : "Edward Wong Hau Pepelu Tivrusky IV
(エドワード・ウォン・ハウ・ペペル・チブルスキー4世 …………",
"title" : "Who is Ed Wong",
"authorId" : "59f4c0f37718af0b1e001071",
"id" : "59f4c12e7718af0b1e001072" },
. . . . . .
]
Simple Blog
#GraphQlVsRest
@VladimirD_42
$ curl http://localhost:8080/posts | json_pp
[
{
"body" : "Edward Wong Hau Pepelu Tivrusky IV
(エドワード・ウォン・ハウ・ペペル・チブルスキー4世 …………",
"title" : "Who is Ed Wong",
"authorId" : "59f4c0f37718af0b1e001071",
"id" : "59f4c12e7718af0b1e001072" },
. . . . . .
]
Simple Blog
#GraphQlVsRest
@VladimirD_42
$ curl http://localhost:8080/posts | json_pp
[
{
"body" : "Edward Wong Hau Pepelu Tivrusky IV
(エドワード・ウォン・ハウ・ペペル・チブルスキー4世 …………",
"title" : "Who is Ed Wong",
"authorId" : "59f4c0f37718af0b1e001071",
"id" : "59f4c12e7718af0b1e001072" },
. . . . . .
]
Simple Blog
#GraphQlVsRest
@VladimirD_42
$ curl
http://localhost:8080/authors/59f4c0f37718af0b1e0010
71 | json_pp
{
"name" : "Ed Wong",
"id" : "59f4c0f37718af0b1e001071”
}
Simple Blog
#GraphQlVsRest
@VladimirD_42
$ curl
http://localhost:8080/comments?post_id=59f4c12e7718a
f0b1e001072 | json_pp
[
{
"authorId" : "59f4c1687718af0b1e001073",
"text" : "you are great",
"id" : "59f4c3327718af0b1e001076",
"postId" : "59f4c12e7718af0b1e001072”
}
]
Simple Blog
#GraphQlVsRest
@VladimirD_42
Simple Blog
Simple REST API use case
#GraphQlVsRest
@VladimirD_42
Simple Blog
Simple REST API use case
‘‘Real enough’’
#GraphQlVsRest
@VladimirD_42
Simple Blog
Simple REST API use case
‘‘Real enough’’
Easy to extended, make complex
What is
GraphQL?
#GraphQlVsRest
#GraphQlVsRest
@VladimirD_42
GraphQL History
#GraphQlVsRest
@VladimirD_42
GraphQL History
Facebook internally 2012
#GraphQlVsRest
@VladimirD_42
GraphQL History
Public release 2015
Facebook internally 2012
#GraphQlVsRest
@VladimirD_42
GraphQL
GraphQL is a query language
for APIs
#GraphQlVsRest
@VladimirD_42
GraphQL
is
Specification
#GraphQlVsRest
@VladimirD_42
Talking is boring
Show us Code
#GraphQlVsRest
@VladimirD_42
$ cat src/main/resources/schema.graphqls
type Author {
id: ID!
name: String!
}
type Post {
id: ID!
title: String!
body: String
authorId: String!
} . . . .
All Start with Schema
#GraphQlVsRest
@VladimirD_42
$ cat src/main/resources/schema.graphqls
type Author {
id: ID!
name: String!
}
type Post {
id: ID!
title: String!
body: String
authorId: String!
} . . . .
All Start with Schema
#GraphQlVsRest
@VladimirD_42
$ cat src/main/resources/schema.graphqls
type Author {
id: ID!
name: String!
}
type Post {
id: ID!
title: String!
body: String
authorId: String!
} . . . .
All Start with Schema
#GraphQlVsRest
@VladimirD_42
$ cat src/main/resources/schema.graphqls
type Author {
id: ID!
name: String!
}
type Post {
id: ID!
title: String!
body: String
authorId: String!
} . . . .
All Start with Schema
#GraphQlVsRest
@VladimirD_42
$ cat src/main/resources/schema.graphqls
type Author {
id: ID!
name: String!
}
type Post {
id: ID!
title: String!
body: String
authorId: String!
} . . . .
All Start with Schema
#GraphQlVsRest
@VladimirD_42
$ cat src/main/resources/schema.graphqls
type Author {
id: ID!
name: String!
}
type Post {
id: ID!
title: String!
body: String
authorId: String!
} . . . .
All Start with Schema
#GraphQlVsRest
@VladimirD_42
$ cat src/main/resources/schema.graphqls
type Author {
id: ID!
name: String!
}
type Post {
id: ID!
title: String!
body: String
authorId: String!
} . . . .
All Start with Schema
#GraphQlVsRest
@VladimirD_42
$ cat src/main/resources/schema.graphqls
type Author {
id: ID!
name: String!
}
type Post {
id: ID!
title: String!
body: String
authorId: String!
} . . . .
All Start with Schema
#GraphQlVsRest
@VladimirD_42
$ cat src/main/resources/schema.graphqls
type Author {
id: ID!
name: String!
}
type Post {
id: ID!
title: String!
body: String
authorId: String!
} . . . .
All Start with Schema
#GraphQlVsRest
@VladimirD_42
$ cat src/main/resources/schema.graphqls
type Author {
id: ID!
name: String!
}
type Post {
id: ID!
title: String!
body: String
authorId: String!
} . . . .
All Start with Schema
#GraphQlVsRest
@VladimirD_42
$ cat src/main/resources/schema.graphqls
. . . .
type Comment {
id: ID!
authorId: String!
postId: String!
text: String
}
. . . .
All Start with Schema
#GraphQlVsRest
@VladimirD_42
$ cat src/main/resources/schema.graphqls
. . . .
schema {
query: Query
}
type Query {
allPosts: [Post]
}
All Start with Schema
#GraphQlVsRest
@VladimirD_42
$ cat src/main/resources/schema.graphqls
. . . .
schema {
query: Query
}
type Query {
allPosts: [Post]
}
All Start with Schema
#GraphQlVsRest
@VladimirD_42
$ cat src/main/resources/schema.graphqls
. . . .
schema {
query: Query
}
type Query {
allPosts: [Post]
}
All Start with Schema
#GraphQlVsRest
@VladimirD_42
$ cat src/main/resources/schema.graphqls
. . . .
schema {
query: Query
}
type Query {
allPosts: [Post]
}
All Start with Schema
#GraphQlVsRest
@VladimirD_42
$ cat src/main/resources/schema.graphqls
. . . .
schema {
query: Query
}
type Query {
allPosts: [Post]
}
All Start with Schema
#GraphQlVsRest
@VladimirD_42
$ cat src/main/resources/schema.graphqls
. . . .
schema {
query: Query
}
type Query {
allPosts: [Post]
}
All Start with Schema
#GraphQlVsRest
@VladimirD_42
Author, Post and Comment POJO are same
Repositories are same
Code
#GraphQlVsRest
@VladimirD_42
public class GraphQLEntryPoint extends
SimpleGraphQLServlet {
public
GraphQLEntryPoint(PostRepository p) {
super(buildSchema(p));
}
private static GraphQLSchema
buildSchema(PostRepository p) {
return SchemaParser.newParser()
.file("schema.graphqls")
.resolvers(new Query(postRepository))
.build().makeExecutableSchema();
}
}
#GraphQlVsRest
@VladimirD_42
public class GraphQLEntryPoint extends
SimpleGraphQLServlet {
public
GraphQLEntryPoint(PostRepository p) {
super(buildSchema(p));
}
private static GraphQLSchema
buildSchema(PostRepository p) {
return SchemaParser.newParser()
.file("schema.graphqls")
.resolvers(new Query(postRepository))
.build().makeExecutableSchema();
}
}
#GraphQlVsRest
@VladimirD_42
public class GraphQLEntryPoint extends
SimpleGraphQLServlet {
public
GraphQLEntryPoint(PostRepository p) {
super(buildSchema(p));
}
private static GraphQLSchema
buildSchema(PostRepository p) {
return SchemaParser.newParser()
.file("schema.graphqls")
.resolvers(new Query(postRepository))
.build().makeExecutableSchema();
}
}
#GraphQlVsRest
@VladimirD_42
public class GraphQLEntryPoint extends
SimpleGraphQLServlet {
public
GraphQLEntryPoint(PostRepository p) {
super(buildSchema(p));
}
private static GraphQLSchema
buildSchema(PostRepository p) {
return SchemaParser.newParser()
.file("schema.graphqls")
.resolvers(new Query(postRepository))
.build().makeExecutableSchema();
}
}
#GraphQlVsRest
@VladimirD_42
public class GraphQLEntryPoint extends
SimpleGraphQLServlet {
public
GraphQLEntryPoint(PostRepository p) {
super(buildSchema(p));
}
private static GraphQLSchema
buildSchema(PostRepository p) {
return SchemaParser.newParser()
.file("schema.graphqls")
.resolvers(new Query(postRepository))
.build().makeExecutableSchema();
}
}
#GraphQlVsRest
@VladimirD_42
public class GraphQLEntryPoint extends
SimpleGraphQLServlet {
public
GraphQLEntryPoint(PostRepository p) {
super(buildSchema(p));
}
private static GraphQLSchema
buildSchema(PostRepository p) {
return SchemaParser.newParser()
.file("schema.graphqls")
.resolvers(new Query(postRepository))
.build().makeExecutableSchema();
}
}
#GraphQlVsRest
@VladimirD_42
public class GraphQLEntryPoint extends
SimpleGraphQLServlet {
public
GraphQLEntryPoint(PostRepository p) {
super(buildSchema(p));
}
private static GraphQLSchema
buildSchema(PostRepository p) {
return SchemaParser.newParser()
.file("schema.graphqls")
.resolvers(new Query(postRepository))
.build().makeExecutableSchema();
}
}
#GraphQlVsRest
@VladimirD_42
public class GraphQLEntryPoint extends
SimpleGraphQLServlet {
public
GraphQLEntryPoint(PostRepository p) {
super(buildSchema(p));
}
private static GraphQLSchema
buildSchema(PostRepository p) {
return SchemaParser.newParser()
.file("schema.graphqls")
.resolvers(new Query(postRepository))
.build().makeExecutableSchema();
}
}
#GraphQlVsRest
@VladimirD_42
public class GraphQLEntryPoint extends
SimpleGraphQLServlet {
public
GraphQLEntryPoint(PostRepository p) {
super(buildSchema(p));
}
private static GraphQLSchema
buildSchema(PostRepository p) {
return SchemaParser.newParser()
.file("schema.graphqls")
.resolvers(new Query(postRepository))
.build().makeExecutableSchema();
}
}
#GraphQlVsRest
@VladimirD_42
@RequiredArgsConstructorpublic
class Query implements GraphQLRootResolver {
private final PostRepository postRepository;
public List<Post> allPosts() {
return postRepository.findAll();
}
}
#GraphQlVsRest
@VladimirD_42
@RequiredArgsConstructorpublic
class Query implements GraphQLRootResolver {
private final PostRepository postRepository;
public List<Post> allPosts() {
return postRepository.findAll();
}
}
#GraphQlVsRest
@VladimirD_42
@RequiredArgsConstructorpublic
class Query implements GraphQLRootResolver {
private final PostRepository postRepository;
public List<Post> allPosts() {
return postRepository.findAll();
}
}
#GraphQlVsRest
@VladimirD_42
@RequiredArgsConstructorpublic
class Query implements GraphQLRootResolver {
private final PostRepository postRepository;
public List<Post> allPosts() {
return postRepository.findAll();
}
}
#GraphQlVsRest
@VladimirD_42
Request
query {
allPosts {
authorId
id
title
body
}
}
#GraphQlVsRest
@VladimirD_42
Response
{
"data": {
"allPosts": [
{
"authorId": "59f4c0f37718af0b1e001071",
"id": "59f4c12e7718af0b1e001072",
"title": "Who is Ed Wong",
"body": "Edward Wong Hau Pepelu .....”
},
. . . .
}
#GraphQlVsRest
@VladimirD_42
Request
query {
allPosts {
authorId
title
}
}
#GraphQlVsRest
@VladimirD_42
Response
{
"data": {
"allPosts": [
{
"authorId": "59f4c0f37718af0b1e001071",
"title": "Who is Ed Wong",
},
. . . .
}
#GraphQlVsRest
@VladimirD_42
$ cat src/main/resources/schema.graphqls
. . .
type Post {
id: ID!
title: String!
body: String
createdBy: Author!
} . . . .
#GraphQlVsRest
@VladimirD_42
private static GraphQLSchema
buildSchema(PostRepository postRepository,
AuthorRepository authRepository) {
return SchemaParser.newParser()
.file("schema.graphqls")
.resolvers(new Query(postRepository),
new PostResolver(authRepository))
.build().makeExecutableSchema();
}
#GraphQlVsRest
@VladimirD_42
@RequiredArgsConstructor
public class PostResolver implements
GraphQLResolver<Post> {
private final AuthorRepository authRepository;
public Author createdBy(Post post) {
return
authRepository
.findOne(post.getAuthorId());
}
}
#GraphQlVsRest
@VladimirD_42
@RequiredArgsConstructor
public class PostResolver implements
GraphQLResolver<Post> {
private final AuthorRepository authRepository;
public Author createdBy(Post post) {
return
authRepository
.findOne(post.getAuthorId());
}
}
#GraphQlVsRest
@VladimirD_42
@RequiredArgsConstructor
public class PostResolver implements
GraphQLResolver<Post> {
private final AuthorRepository authRepository;
public Author createdBy(Post post) {
return
authRepository
.findOne(post.getAuthorId());
}
}
#GraphQlVsRest
@VladimirD_42
@RequiredArgsConstructor
public class PostResolver implements
GraphQLResolver<Post> {
private final AuthorRepository authRepository;
public Author createdBy(Post post) {
return
authRepository
.findOne(post.getAuthorId());
}
}
#GraphQlVsRest
@VladimirD_42
@RequiredArgsConstructor
public class PostResolver implements
GraphQLResolver<Post> {
private final AuthorRepository authRepository;
public Author createdBy(Post post) {
return
authRepository
.findOne(post.getAuthorId());
}
}
#GraphQlVsRest
@VladimirD_42
@RequiredArgsConstructor
public class PostResolver implements
GraphQLResolver<Post> {
private final AuthorRepository authRepository;
public Author createdBy(Post post) {
return
authRepository
.findOne(post.getAuthorId());
}
}
#GraphQlVsRest
@VladimirD_42
Request
{
query {
allPosts {
title
createdBy {
name
}
}
}
}
#GraphQlVsRest
@VladimirD_42
Request
{
query {
allPosts {
title
createdBy {
name
}
}
}
}
#GraphQlVsRest
@VladimirD_42
Response
{
"data": {
"allPosts": [
{
"title": "Who is Ed Wong",
"createdBy": {
"name": "Ed Wong”
}
},
. . .
]
}
#GraphQlVsRest
@VladimirD_42
type Author {
id: ID!
name: String!
posts: [Post]
}
type Post {
id: ID!
title: String!
body: String
createdBy: Author!
comments: [Comment]
}
#GraphQlVsRest
@VladimirD_42
type Author {
id: ID!
name: String!
posts: [Post]
}
type Post {
id: ID!
title: String!
body: String
createdBy: Author!
comments: [Comment]
}
#GraphQlVsRest
@VladimirD_42
type Author {
id: ID!
name: String!
posts: [Post]
}
type Post {
id: ID!
title: String!
body: String
createdBy: Author!
comments: [Comment]
}
#GraphQlVsRest
@VladimirD_42
type Author {
id: ID!
name: String!
posts: [Post]
}
type Post {
id: ID!
title: String!
body: String
createdBy: Author!
comments: [Comment]
}
#GraphQlVsRest
@VladimirD_42
type Author {
id: ID!
name: String!
posts: [Post]
}
type Post {
id: ID!
title: String!
body: String
createdBy: Author!
comments: [Comment]
}
#GraphQlVsRest
@VladimirD_42
type Author {
id: ID!
name: String!
posts: [Post]
}
type Post {
id: ID!
title: String!
body: String
createdBy: Author!
comments: [Comment]
}
#GraphQlVsRest
@VladimirD_42
type Comment {
id: ID!
createdBy: Author!
belongsTo: Post!
text: String
}
#GraphQlVsRest
@VladimirD_42
type Comment {
id: ID!
createdBy: Author!
belongsTo: Post!
text: String
}
#GraphQlVsRest
@VladimirD_42
type Comment {
id: ID!
createdBy: Author!
belongsTo: Post!
text: String
}
#GraphQlVsRest
@VladimirD_42
type Comment {
id: ID!
createdBy: Author!
belongsTo: Post!
text: String
}
#GraphQlVsRest
@VladimirD_42
type Comment {
id: ID!
createdBy: Author!
belongsTo: Post!
text: String
}
#GraphQlVsRest
@VladimirD_42
Request
query {
allPosts {
title
comments {
text
createdBy {
name
posts {
title
comments {
text
. . . .
#GraphQlVsRest
@VladimirD_42
Request
query {
allPosts {
title
comments {
text
createdBy {
name
posts {
title
comments {
text
. . . .
#GraphQlVsRest
@VladimirD_42
Protect from Abuse
#GraphQlVsRest
@VladimirD_42
Protect from Abuse
Time out
#GraphQlVsRest
@VladimirD_42
Protect from Abuse
Time out
Max Query Depth
#GraphQlVsRest
@VladimirD_42
Protect from Abuse
Time out
Max Query Depth
Max Query Complexity
#GraphQlVsRest
@VladimirD_42
Protect from Abuse
Time out
Max Query Depth
Max Query Complexity
Throttling
#GraphQlVsRest
@VladimirD_42
Mutation
#GraphQlVsRest
@VladimirD_42
$ cat src/main/resources/schema.graphqls
. . . .
schema {
query: Query
mutation: Mutation
}
type Mutation {
addAuthor(name: String!) : Author
removeAuthour(id: ID!): Author
}
. . . .
#GraphQlVsRest
@VladimirD_42
$ cat src/main/resources/schema.graphqls
. . . .
schema {
query: Query
mutation: Mutation
}
type Mutation {
addAuthor(name: String!) : Author
removeAuthour(id: ID!): Author
}
. . . .
#GraphQlVsRest
@VladimirD_42
$ cat src/main/resources/schema.graphqls
. . . .
schema {
query: Query
mutation: Mutation
}
type Mutation {
addAuthor(name: String!) : Author
removeAuthour(id: ID!): Author
}
. . . .
#GraphQlVsRest
@VladimirD_42
$ cat src/main/resources/schema.graphqls
. . . .
schema {
query: Query
mutation: Mutation
}
type Mutation {
addAuthor(name: String!) : Author
removeAuthour(id: ID!): Author
}
. . . .
#GraphQlVsRest
@VladimirD_42
$ cat src/main/resources/schema.graphqls
. . . .
schema {
query: Query
mutation: Mutation
}
type Mutation {
addAuthor(name: String!) : Author
removeAuthour(id: ID!): Author
}
. . . .
#GraphQlVsRest
@VladimirD_42
$ cat src/main/resources/schema.graphqls
. . . .
schema {
query: Query
mutation: Mutation
}
type Mutation {
addAuthor(name: String!) : Author
removeAuthour(id: ID!): Author
}
. . . .
#GraphQlVsRest
@VladimirD_42
$ cat src/main/resources/schema.graphqls
. . . .
schema {
query: Query
mutation: Mutation
}
type Mutation {
addAuthor(name: String!) : Author
removeAuthour(id: ID!): Author
}
. . . .
#GraphQlVsRest
@VladimirD_42
$ cat src/main/resources/schema.graphqls
. . . .
schema {
query: Query
mutation: Mutation
}
type Mutation {
addAuthor(name: String!) : Author
removeAuthour(id: ID!): Author
}
. . . .
#GraphQlVsRest
@VladimirD_42
$ cat src/main/resources/schema.graphqls
. . . .
schema {
query: Query
mutation: Mutation
}
type Mutation {
addAuthor(name: String!) : Author
removeAuthour(id: ID!): Author
}
. . . .
#GraphQlVsRest
@VladimirD_42
$ cat src/main/resources/schema.graphqls
. . . .
schema {
query: Query
mutation: Mutation
}
type Mutation {
addAuthor(name: String!) : Author
removeAuthour(id: ID!): Author
}
. . . .
#GraphQlVsRest
@VladimirD_42
$ cat src/main/resources/schema.graphqls
. . . .
schema {
query: Query
mutation: Mutation
}
type Mutation {
addAuthor(name: String!) : Author
removeAuthour(id: ID!): Author
}
. . . .
#GraphQlVsRest
@VladimirD_42
$ cat src/main/resources/schema.graphqls
. . . .
schema {
query: Query
mutation: Mutation
}
type Mutation {
addAuthor(name: String!) : Author
removeAuthour(id: ID!): Author
}
. . . .
#GraphQlVsRest
@VladimirD_42
private static GraphQLSchema
buildSchema(PostRepository pr,
AuthorRepository ar,
CommentRepository cr) {
return SchemaParser
.newParser().file("schema.graphqls")
.resolvers(
new Query(pr,ar),
new Mutation(ar),
new PostResolver(ar,cr),
new AuthorResolver(pr),
new CommentResolver(ar,pr))
.build().makeExecutableSchema();
}
#GraphQlVsRest
@VladimirD_42
private static GraphQLSchema
buildSchema(PostRepository pr,
AuthorRepository ar,
CommentRepository cr) {
return SchemaParser
.newParser().file("schema.graphqls")
.resolvers(
new Query(pr,ar),
new Mutation(ar),
new PostResolver(ar,cr),
new AuthorResolver(pr),
new CommentResolver(ar,pr))
.build().makeExecutableSchema();
}
#GraphQlVsRest
@VladimirD_42
private static GraphQLSchema
buildSchema(PostRepository pr,
AuthorRepository ar,
CommentRepository cr) {
return SchemaParser
.newParser().file("schema.graphqls")
.resolvers(
new Query(pr,ar),
new Mutation(ar),
new PostResolver(ar,cr),
new AuthorResolver(pr),
new CommentResolver(ar,pr))
.build().makeExecutableSchema();
}
#GraphQlVsRest
@VladimirD_42
private static GraphQLSchema
buildSchema(PostRepository pr,
AuthorRepository ar,
CommentRepository cr) {
return SchemaParser
.newParser().file("schema.graphqls")
.resolvers(
new Query(pr,ar),
new Mutation(ar),
new PostResolver(ar,cr),
new AuthorResolver(pr),
new CommentResolver(ar,pr))
.build().makeExecutableSchema();
}
#GraphQlVsRest
@VladimirD_42
public class Mutation
implements GraphQLRootResolver {
private final AuthorRepository authRepo;
public Author addAuthor(String name) {
return authRepo.save(new Author(null, name));
}
public Author removeAuthour(String id) {
Author auth = authRepo.findOne(id);
authRepo.delete(id); return auth;
}
}
#GraphQlVsRest
@VladimirD_42
public class Mutation
implements GraphQLRootResolver {
private final AuthorRepository authRepo;
public Author addAuthor(String name) {
return authRepo.save(new Author(null, name));
}
public Author removeAuthour(String id) {
Author auth = authRepo.findOne(id);
authRepo.delete(id); return auth;
}
}
#GraphQlVsRest
@VladimirD_42
public class Mutation
implements GraphQLRootResolver {
private final AuthorRepository authRepo;
public Author addAuthor(String name) {
return authRepo.save(new Author(null, name));
}
public Author removeAuthour(String id) {
Author auth = authRepo.findOne(id);
authRepo.delete(id); return auth;
}
}
#GraphQlVsRest
@VladimirD_42
public class Mutation
implements GraphQLRootResolver {
private final AuthorRepository authRepo;
public Author addAuthor(String name) {
return authRepo.save(new Author(null, name));
}
public Author removeAuthour(String id) {
Author auth = authRepo.findOne(id);
authRepo.delete(id); return auth;
}
}
#GraphQlVsRest
@VladimirD_42
public class Mutation
implements GraphQLRootResolver {
private final AuthorRepository authRepo;
public Author addAuthor(String name) {
return authRepo.save(new Author(null, name));
}
public Author removeAuthour(String id) {
Author auth = authRepo.findOne(id);
authRepo.delete(id); return auth;
}
}
#GraphQlVsRest
@VladimirD_42
public class Mutation
implements GraphQLRootResolver {
private final AuthorRepository authRepo;
public Author addAuthor(String name) {
return authRepo.save(new Author(null, name));
}
public Author removeAuthour(String id) {
Author auth = authRepo.findOne(id);
authRepo.delete(id); return auth;
}
}
#GraphQlVsRest
@VladimirD_42
public class Mutation
implements GraphQLRootResolver {
private final AuthorRepository authRepo;
public Author addAuthor(String name) {
return authRepo.save(new Author(null, name));
}
public Author removeAuthour(String id) {
Author auth = authRepo.findOne(id);
authRepo.delete(id); return auth;
}
}
#GraphQlVsRest
@VladimirD_42
public class Mutation
implements GraphQLRootResolver {
private final AuthorRepository authRepo;
public Author addAuthor(String name) {
return authRepo.save(new Author(null, name));
}
public Author removeAuthour(String id) {
Author auth = authRepo.findOne(id);
authRepo.delete(id); return auth;
}
}
#GraphQlVsRest
@VladimirD_42
public class Mutation
implements GraphQLRootResolver {
private final AuthorRepository authRepo;
public Author addAuthor(String name) {
return authRepo.save(new Author(null, name));
}
public Author removeAuthour(String id) {
Author auth = authRepo.findOne(id);
authRepo.delete(id); return auth;
}
}
#GraphQlVsRest
@VladimirD_42
public class Mutation
implements GraphQLRootResolver {
private final AuthorRepository authRepo;
public Author addAuthor(String name) {
return authRepo.save(new Author(null, name));
}
public Author removeAuthour(String id) {
Author auth = authRepo.findOne(id);
authRepo.delete(id); return auth;
}
}
#GraphQlVsRest
@VladimirD_42
Request
mutation {
addAuthor (name: " Gon Freecss") {
name
}
}
#GraphQlVsRest
@VladimirD_42
Response
{
"data": {
"addAuthor": {
"name": " Gon Freecss”
}
}
}
#GraphQlVsRest
@VladimirD_42
Subscription
#GraphQlVsRest
@VladimirD_42
Subscription
Realtime Updates
#GraphQlVsRest
@VladimirD_42
Subscription
Realtime Updates
Not supported by all implementations
#GraphQlVsRest
@VladimirD_42
Caching
#GraphQlVsRest
@VladimirD_42
Caching
Different approach
Is needed
#GraphQlVsRest
@VladimirD_42
Paramaters
#GraphQlVsRest
@VladimirD_42
Paramaters
Like in Mutation
#GraphQlVsRest
@VladimirD_42
Headers/Cookies
#GraphQlVsRest
@VladimirD_42
class MyCustomContext extends GraphQLContext
. . . .
@Override
protected GraphQLContext
createContext(Optional<HttpServletRequest> r,
Optional<HttpServletResponse> response) {
. . . .
return MyCustomContext
}
. . . .
public ? <method>(<args>,
DataFetchingEnvironment env) {
MyCustomContext con = env.getContext();
. . . .
#GraphQlVsRest
@VladimirD_42
class MyCustomContext extends GraphQLContext
. . . .
@Override
protected GraphQLContext
createContext(Optional<HttpServletRequest> r,
Optional<HttpServletResponse> response) {
. . . .
return MyCustomContext
}
. . . .
public ? <method>(<args>,
DataFetchingEnvironment env) {
MyCustomContext con = env.getContext();
. . . .
#GraphQlVsRest
@VladimirD_42
class MyCustomContext extends GraphQLContext
. . . .
@Override
protected GraphQLContext
createContext(Optional<HttpServletRequest> r,
Optional<HttpServletResponse> response) {
. . . .
return MyCustomContext
}
. . . .
public ? <method>(<args>,
DataFetchingEnvironment env) {
MyCustomContext con = env.getContext();
. . . .
#GraphQlVsRest
@VladimirD_42
class MyCustomContext extends GraphQLContext
. . . .
@Override
protected GraphQLContext
createContext(Optional<HttpServletRequest> r,
Optional<HttpServletResponse> response) {
. . . .
return MyCustomContext
}
. . . .
public ? <method>(<args>,
DataFetchingEnvironment env) {
MyCustomContext con = env.getContext();
. . . .
#GraphQlVsRest
@VladimirD_42
class MyCustomContext extends GraphQLContext
. . . .
@Override
protected GraphQLContext
createContext(Optional<HttpServletRequest> r,
Optional<HttpServletResponse> response) {
. . . .
return MyCustomContext
}
. . . .
public ? <method>(<args>,
DataFetchingEnvironment env) {
MyCustomContext con = env.getContext();
. . . .
#GraphQlVsRest
@VladimirD_42
class MyCustomContext extends GraphQLContext
. . . .
@Override
protected GraphQLContext
createContext(Optional<HttpServletRequest> r,
Optional<HttpServletResponse> response) {
. . . .
return MyCustomContext
}
. . . .
public ? <method>(<args>,
DataFetchingEnvironment env) {
MyCustomContext con = env.getContext();
. . . .
#GraphQlVsRest
@VladimirD_42
class MyCustomContext extends GraphQLContext
. . . .
@Override
protected GraphQLContext
createContext(Optional<HttpServletRequest> r,
Optional<HttpServletResponse> response) {
. . . .
return MyCustomContext
}
. . . .
public ? <method>(<args>,
DataFetchingEnvironment env) {
MyCustomContext con = env.getContext();
. . . .
#GraphQlVsRest
@VladimirD_42
class MyCustomContext extends GraphQLContext
. . . .
@Override
protected GraphQLContext
createContext(Optional<HttpServletRequest> r,
Optional<HttpServletResponse> response) {
. . . .
return MyCustomContext
}
. . . .
public ? <method>(<args>,
DataFetchingEnvironment env) {
MyCustomContext con = env.getContext();
. . . .
#GraphQlVsRest
@VladimirD_42
class MyCustomContext extends GraphQLContext
. . . .
@Override
protected GraphQLContext
createContext(Optional<HttpServletRequest> r,
Optional<HttpServletResponse> response) {
. . . .
return MyCustomContext
}
. . . .
public ? <method>(<args>,
DataFetchingEnvironment env) {
MyCustomContext con = env.getContext();
. . . .
#GraphQlVsRest
@VladimirD_42
class MyCustomContext extends GraphQLContext
. . . .
@Override
protected GraphQLContext
createContext(Optional<HttpServletRequest> r,
Optional<HttpServletResponse> response) {
. . . .
return MyCustomContext
}
. . . .
public ? <method>(<args>,
DataFetchingEnvironment env) {
MyCustomContext con = env.getContext();
. . . .
#GraphQlVsRest
@VladimirD_42
class MyCustomContext extends GraphQLContext
. . . .
@Override
protected GraphQLContext
createContext(Optional<HttpServletRequest> r,
Optional<HttpServletResponse> response) {
. . . .
return MyCustomContext
}
. . . .
public ? <method>(<args>,
DataFetchingEnvironment env) {
MyCustomContext con = env.getContext();
. . . .
#GraphQlVsRest
@VladimirD_42
class MyCustomContext extends GraphQLContext
. . . .
@Override
protected GraphQLContext
createContext(Optional<HttpServletRequest> r,
Optional<HttpServletResponse> response) {
. . . .
return MyCustomContext
}
. . . .
public ? <method>(<args>,
DataFetchingEnvironment env) {
MyCustomContext con = env.getContext();
. . . .
#GraphQlVsRest
@VladimirD_42
class MyCustomContext extends GraphQLContext
. . . .
@Override
protected GraphQLContext
createContext(Optional<HttpServletRequest> r,
Optional<HttpServletResponse> response) {
. . . .
return MyCustomContext
}
. . . .
public ? <method>(<args>,
DataFetchingEnvironment env) {
MyCustomContext con = env.getContext();
. . . .
#GraphQlVsRest
@VladimirD_42
Authentication
#GraphQlVsRest
@VladimirD_42
Authentication
Over custom Context
Conclusion
#GraphQlVsRest
#GraphQlVsRest
@VladimirD_42
GraphQL
Client-Server architecture
Statelessness
Cacheability
Layered system
Code on Demand (Optional)
Uniform Interface
#GraphQlVsRest
@VladimirD_42
GraphQL
Client-Server architecture
Statelessness
Cacheability
Layered system
Code on Demand (Optional)
Uniform Interface
#GraphQlVsRest
@VladimirD_42
GraphQL
Client-Server architecture
Statelessness
Cacheability
Layered system
Code on Demand (Optional)
Uniform Interface
#GraphQlVsRest
@VladimirD_42
GraphQL
Client-Server architecture
Statelessness
Cacheability
Layered system
Code on Demand (Optional)
Uniform Interface
#GraphQlVsRest
@VladimirD_42
GraphQL
Client-Server architecture
Statelessness
Cacheability
Layered system
Code on Demand (Optional)
Uniform Interface
#GraphQlVsRest
@VladimirD_42
GraphQL
Client-Server architecture
Statelessness
Cacheability
Layered system
Code on Demand (Optional)
Uniform Interface
#GraphQlVsRest
@VladimirD_42
GraphQL
Client-Server architecture
Statelessness
Cacheability
Layered system
Code on Demand (Optional)
Uniform Interface
#GraphQlVsRest
@VladimirD_42
$ curl -H "Content-Type: application/json" -X POST
-d '{"query":"query {allPosts { title }}",
"variables":null}' http://localhost:8080/graphql |
json_pp
{
"data" : {
"allPosts" : [
{
"title" : "Who is Ed Wong”
}, {
"title" : "Who is Son Goku”
},
. . . .
#GraphQlVsRest
@VladimirD_42
$ curl -H "Content-Type: application/json" -X POST
-d '{"query":"query {allPosts { title }}",
"variables":null}' http://localhost:8080/graphql |
json_pp
{
"data" : {
"allPosts" : [
{
"title" : "Who is Ed Wong”
}, {
"title" : "Who is Son Goku”
},
. . . .
#GraphQlVsRest
@VladimirD_42
$ curl -H "Content-Type: application/json" -X POST
-d '{"query":"query {allPosts { title }}",
"variables":null}' http://localhost:8080/graphql |
json_pp
{
"data" : {
"allPosts" : [
{
"title" : "Who is Ed Wong”
}, {
"title" : "Who is Son Goku”
},
. . . .
#GraphQlVsRest
@VladimirD_42
$ curl -H "Content-Type: application/json" -X POST
-d '{"query":"query {allPosts { title }}",
"variables":null}' http://localhost:8080/graphql |
json_pp
{
"data" : {
"allPosts" : [
{
"title" : "Who is Ed Wong”
}, {
"title" : "Who is Son Goku”
},
. . . .
#GraphQlVsRest
@VladimirD_42
$ curl -H "Content-Type: application/json" -X POST
-d '{"query":"query {allPosts { title }}",
"variables":null}' http://localhost:8080/graphql |
json_pp
{
"data" : {
"allPosts" : [
{
"title" : "Who is Ed Wong”
}, {
"title" : "Who is Son Goku”
},
. . . .
#GraphQlVsRest
@VladimirD_42
$ curl -H "Content-Type: application/json" -X POST
-d '{"query":"query {allPosts { title }}",
"variables":null}' http://localhost:8080/graphql |
json_pp
{
"data" : {
"allPosts" : [
{
"title" : "Who is Ed Wong”
}, {
"title" : "Who is Son Goku”
},
. . . .
#GraphQlVsRest
@VladimirD_42
$ curl -H "Content-Type: application/json" -X POST
-d '{"query":"query {allPosts { title }}",
"variables":null}' http://localhost:8080/graphql |
json_pp
{
"data" : {
"allPosts" : [
{
"title" : "Who is Ed Wong”
}, {
"title" : "Who is Son Goku”
},
. . . .
#GraphQlVsRest
@VladimirD_42
$ curl -H "Content-Type: application/json" -X POST
-d '{"query":"query {allPosts { title }}",
"variables":null}' http://localhost:8080/graphql |
json_pp
{
"data" : {
"allPosts" : [
{
"title" : "Who is Ed Wong”
}, {
"title" : "Who is Son Goku”
},
. . . .
#GraphQlVsRest
@VladimirD_42
$ curl -H "Content-Type: application/json" -X POST
-d '{"query":"query {allPosts { title }}",
"variables":null}' http://localhost:8080/graphql |
json_pp
{
"data" : {
"allPosts" : [
{
"title" : "Who is Ed Wong”
}, {
"title" : "Who is Son Goku”
},
. . . .
#GraphQlVsRest
@VladimirD_42
SOA and WSDL?
#GraphQlVsRest
@VladimirD_42
https://neurocapability.files.wordpress.com/2012/08/businessman-asleep-meeting-istock.jpg
#GraphQlVsRest
@VladimirD_42
#GraphQlVsRest
@VladimirD_42
HAL
#GraphQlVsRest
@VladimirD_42
HAL
Adopting HAL will make your API
explorable, and its documentation
easily discoverable from within the
API itself.
#GraphQlVsRest
@VladimirD_42
Code Examples
https://github.com/vladimir-dejanovic/simple-sp
ringboot-rest-mongo-conftalk-demo
https://github.com/vladimir-dejanovic/simple-sp
ringboot-graphql-mongo-conftalk-demo
Thank You
#GraphQlVsRest
#GraphQlVsRest
@VladimirD_42
Questions
@VladimirD_42
ed.wong.iv@gmail.com

GraphQL vs Traditional Rest API