SlideShare uma empresa Scribd logo
1 de 85
Baixar para ler offline
Marcin Stachniuk
stachniuk.com
/mstachniuk/graphql-java-example
@MarcinStachniuk
wroclaw.jug.pl
shipkit.org
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
What is NOT GraphQL
GraphQL =/= Graph (math)
GraphQL =/= GQL Standard
GraphQL =/= openCypher, PGQL, GSQL, and G-CORE
GraphQL =/= DQL (GraphQL+-) in Dgraph
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
What is GraphQL
GraphQL == language for API
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
Who is using REST?
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
REST - REpresentational State Transfer
https://api.example.com/customers/123
DELETE
PUT
POST
GET
PATCH
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
Issues with REST
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
Different clients - different needs
Application
Web iPhone Android TV
Independent
deploym
ent
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
REST fixed response
GET /customers/111
{
"customer": {
"id": "111",
"name": "John Doe",
"email": "john@doe.com",
"company": {
"id": "222"
},
"orders": [
{
"id": "333"
},
{
"id": "444"
}
]
}
}
{
"customer": {
"id": "111",
"name": "John Doe",
"email": "john@doe.com",
"company": {
"href": "https://api.example.com/companies/222"
},
"orders": [
{
"href": "https://api.example.com/orders/333"
},
{
"href": "https://api.example.com/orders/444"
}
]
}
}
RE
ST
Easy
selectw
hat
you
need
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
REST consequences: several roundtrips
U
nderFetching
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
REST response with nested data
GET /customers/111
{
"customer": {
"id": "111",
"name": "John Doe",
"email": "john@doe.com",
"company": {
"id": "222",
"name": "My Awesome Corporation",
"website": "MyAwesomeCorporation.com"
},
"orders": [
{
"id": "333",
"status": "delivered",
"items": [
{
"id": "555",
"name": "Silver Bullet",
"amount": "42",
"price": "10000000",
"currency": "USD",
"producer": {
"id": "777",
"name": "Lorem Ipsum",
"website": "LoremIpsum.com"
}
}
]
},
{
"id": "444",
"name": "Golden Hammer",
"amount": "5",
"price": "10000",
"currency": "USD",
"producer": {
...
}
}
] } }
RE
ST
O
verFetching
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
REST API Versioning
GET /v2/customers/111RE
ST
GET /customers/111?v=v2RE
ST
GET /customers/111 Accept header: application/vnd.myapp.2+jsonRE
ST
GET /customers/111 Custom header: x-ms-version:2RE
ST
A
PIversioning
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
REST API as independent resources
GET /customersRE
ST
GET /usersRE
ST
GET /ordersRE
ST
GET /itemsRE
ST
RE
ST GET /companies
D
istorted
reality
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
Platform Architecture - How to define a good API?
Platform
App 1 App 2
Customer
App X...
G
ood
A
PIforall
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
GraphQL
● Graph Query Language
● Published by Facebook in 2015
● Growth from Facebook Graph API
● Reference implementation in JavaScript
● First version of Java Library: 18 Jul 2015
https://github.com/graphql-java/graphql-java
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
GraphQL main concepts
● One endpoint for all operations
● Always define in request what you need
● Queries, Mutations and Subscriptions
● Defined by schema
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
Data is a graph
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
GraphQL time for demo
● Fragments
● Aliases
● Directives
● Interfaces
● Unions
● Query
● Syntax Error
● Mutation
● Operation name
● Variables
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
GraphQL Simple API
GET /customers/2?fields=id,name,email
type Customer {
#fields with ! are not null
id: ID!
name: String!
email: String!
}
type Query {
customer(id: String!): Customer!
}
{
"data": {
"customer": {
"id": "2",
"name": "name",
"email": "a@b.com"
}
}
}
{
customer(id: "2") {
id
name
email
}
}
RE
ST
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
GraphQL Bad Request
GET /custo!@#$ -> 404
{
"data": null,
"errors": [
{
"message": "Invalid Syntax",
"locations": [
{
"line": 2,
"column": 8
}
],
"errorType": "InvalidSyntax",
"path": null,
"extensions": null
} ] }
{
custo!@#$
}
RE
ST
http.cat/200
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
Go back to the roots
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
GraphQL Simple API
GET /customers/2?fields=id,name,email,company(id,name)
type Customer {
id: ID!
name: String!
email: String!
company: Company
}
type Company {
id: ID!
name: String!
website: String!
}
type Query {
customer(id: String!): Customer!
}
{
"data": {
"customer": {
"id": "2",
"name": "name",
"email": "a@b.com",
"company": {
"id": "211",
"name": "Company Corp."
}
}
}
}
{
customer(id: "2") {
id
name
email
company {
id
name
}
}
}
RE
ST
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
GraphQL Simple API
GET /customers/2?fields=id,name,email,orders(id,status)
type Customer {
id: ID!
name: String!
email: String!
company: Company
orders: [Order]
}
type Order {
id: ID!
status: Status
}
enum Status {
NEW, CANCELED, DONE
}
{
"data": {
"customer": {
"id": "2",
"name": "name",
"orders": [
{
"id": "55",
"status": "NEW"
},
{
"id": "66",
"status": "DONE"
}
] } } }
{
customer(id: "2") {
id
name
orders {
id
status
}
}
}
RE
ST
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
GraphQL Aliases
GET /customers/2?fields=id,name,email +
{
"data": {
"cust1": {
"id": "2",
"name": "name",
"email": "a@b.com"
},
"cust2": {
"id": "3",
"name": "John Doe",
"email": "john@doe.com"
}
}
}
query get2Cust {
cust1: customer(id: "2") {
id
name
email
}
cust2: customer(id: "3") {
id
name
email
}
}
RE
ST GET /customers/3?fields=id,name,emailRE
ST
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
GraphQL Fragment
GET /customers/2?fields=id,name,email +
{
"data": {
"cust1": {
"id": "2",
"name": "name",
"email": "a@b.com"
},
"cust2": {
"id": "3",
"name": "John Doe",
"email": "john@doe.com"
}
}
}
query get2Cust {
cust1: customer(id: "2") {
... frag1
}
cust2: customer(id: "3") {
... frag1
}
}
fragment frag1 on Customer {
id
name
email
}
RE
ST GET /customers/3?fields=id,name,emailRE
ST
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
GraphQL Arguments
GET /customers/2?fields=id,name,email +
{
"data": {
"cust1": {
"id": "2",
"name": "name",
"email": "a@b.com"
},
"cust2": {
"id": "3",
"name": "John Doe",
"email": "john@doe.com"
}
}
}
query get2Cust($arg1:String!, $arg2: String!) {
cust2: customer(id: $arg1) {
... frag1
}
cust3: customer(id: $arg2) {
... frag1
}
}
fragment frag1 on Customer {
id
name
email
}
RE
ST GET /customers/3?fields=id,name,emailRE
ST
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
GraphQL Directive
GET /customers/2?fields=id,name
{
"data": {
"customer": {
"id": "2",
"name": "name"
}
}
}
query getCust ($showEmail: Boolean!) {
customer(id: "2") {
id
name
email @include(if: $showEmail)
}
}
{
"showEmail": false
}
RE
ST
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
GraphQL Interface
GET /users?fields=id,name,superAdmin,permissions
type Query {
users: [User]
}
interface User {
id: ID!
name: String!
email: String!
}
type Admin implements User {
superAdmin: Boolean! // + id...
}
type Moderator implements User {
permissions: [String] // + id...
}
{
"data": {
"users": [
{
"id": "777",
"name": "Admin a",
"superAdmin": true
},
{
"id": "888",
"name": "Moderator",
"permissions": [
"Delete Customer",
"Delete comment"
]}]}}
query getUsers {
users {
... on Admin {
id
name
superAdmin
}
... on Moderator {
id
name
permissions
}
}
}
RE
ST
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
GraphQL Union
GET /search?input=a?fields=typename,name
type Query {
search(input: String):
[SearchResult]
}
union SearchResult =
Customer |
Admin |
Moderator
{
"data": {
"search": [
{
"__typename": "Customer",
"name": "name"
},
{
"__typename": "Admin",
"name": "Admin a"
},
{
"__typename": "Moderator",
"name": "Moderator"
}]}}
query searchSmth {
search(input: "a") {
__typename
... on Customer {
name
}
... on Admin {
name
}
... on Moderator {
name
}
}
}
RE
ST
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
GraphQL mutations
input CreateCustomerInput {
name: String
email: String
clientMutationId: String!
}
type CreateCustomerPayload {
customer: Customer
clientMutationId: String!
}
type Mutation {
createCustomer(input: CreateCustomerInput):
CreateCustomerPayload!
}
{
"data": {
"createCustomer": {
"customer": {
"id": "40",
},
"clientMutationId":
"123"
}
}
}
POST /customers PUT /customers/123 DELETE /customers/123 PATCH /customers/123
mutation {
createCustomer(input: {
name: "MyName"
email: "me@me.com"
clientMutationId: "123"
}) {
customer {
id
}
clientMutationId
}
}
RE
ST
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
GraphQL mutations + operation name
mutation crCust {
createCustomer(input: {
name: "MyName"
email: "me@me.com"
clientMutationId: "123"
}) {
customer {
id
}
clientMutationId
}
}
{
"data": {
"createCustomer": {
"customer": {
"id": "40",
},
"clientMutationId":
"123"
}
}
}
POST /customers PUT /customers/123 DELETE /customers/123 PATCH /customers/123RE
ST
mutation {
createCustomer(input: {
name: "MyName"
email: "me@me.com"
clientMutationId: "123"
}) {
customer {
id
}
clientMutationId
}
}
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
GraphQL Variables
{
"data": {
"createCustomer": {
"customer": {
"id": "40",
},
"clientMutationId":
"123"
}
}
}
POST /customers PUT /customers/123 DELETE /customers/123 PATCH /customers/123
mutation crCust {
createCustomer(input: {
name: "MyName"
email: "me@me.com"
clientMutationId: "123"
}) {
customer {
id
}
clientMutationId
}
}
RE
ST
mutation crCust ($input: CreateCustInput) {
createCustomer(input: $input) {
customer {
id
}
clientMutationId
}
}
{
"input": {
"name": "MyName 2",
"email": "me2@me.com",
"clientMutationId": "123"
}
}
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
GraphQL Java implementations
How to implement GraphQL in Java?
/graphql-java/graphql-java
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
GraphQL type system
How to define your schema?
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
Code First approach / programmatically
private GraphQLFieldDefinition customerDefinition() {
return GraphQLFieldDefinition.newFieldDefinition()
.name("customer")
.argument(GraphQLArgument.newArgument()
.name("id")
.type(new GraphQLNonNull(GraphQLString)))
.type(new GraphQLNonNull(GraphQLObjectType.newObject()
.name("Customer")
.field(GraphQLFieldDefinition.newFieldDefinition()
.name("id")
.description("fields with ! are not null")
.type(new GraphQLNonNull(GraphQLID))
.build())
….
.build()))
.dataFetcher(customerFetcher)
.build();
}
Schema First approach
type Query {
customer(id: String!): Customer!
}
type Customer {
#fields with ! are not null
id: ID!
name: String!
email: String!
company: Company
orders: [Order]
}
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
Schema First approach
type Customer {
# fields with ! are required
id: ID!
name: String!
email: String!
company: Company
orders: [Order]
}
*.graphqls
SchemaParser schemaParser = new SchemaParser();
File file = // ...
TypeDefinitionRegistry registry = schemaParser.parse(file);
SchemaGenerator schemaGenerator = new SchemaGenerator();
RuntimeWiring runtimeWiring = RuntimeWiring.newRuntimeWiring()
.type("Query", builder ->
builder.dataFetcher("customer", customerFetcher))
// ...
.build();
return schemaGenerator.makeExecutableSchema(registry, runtimeWiring);
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
GraphQL SPQR
leangen/graphql-spqr
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
SPQR approach
public class UserService {
@GraphQLQuery(name = "user")
public User getById(@GraphQLArgument(name = "id") Integer id) {
//...
}
}
public class User {
//...
@GraphQLQuery(name = "name", description = "A person's name")
public String getName() {
return name;
}
}
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
SPQR approach - Smart conventions
@GraphQLType(name = "Item")
public class SpqrItem {
private String id;
private int amount;
// ...
@GraphQLId
@GraphQLNonNull
@GraphQLQuery(name = "id", description = "Item id")
public String getId() {
return id;
}
public int getAmount() {
return amount;
}
}
// 'ID' type in schema, add 'implements Node'
// add ! (non null) in schema
// optional
// add ! (non null) because it’s int
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
Classic Code First Approach
Pros:
● Stable library
● Some Javadoc and
documentation
● It was the only way at the
beginning in Java to define a
schema
Cons:
● Hard to maintain
● Missing big picture
● Backend part needs to be
implemented first
● One DataFetcher for one
operation
● No possibility to mix with
Schema First
● No easy way to migrate to
Schema First or SPQR
● Javadoc could be better
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
Schema First Approach
Pros:
● Easy to maintain
● Stable library
● Some Javadoc and
documentation
● Easy DSL to understand and
maintain
● Reduce boilerplate to write
● A possibility to split schema into
more files
● Parallel development (frontend &
backend)
Cons:
● Possible mismatch between
types in schema file and Java
code
● Binding between operations
defined in schema and
DataFetcher's is needed
● One DataFetcher for one
operation
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
SPQR Approach
Pros:
● The author replied to Github
issues quickly
● Reduce boilerplate to write
● No mismatch between Schema
and Java code
● No binding between schema and
DataFetchers is needed
● Smart conventions
Cons:
● Development is frozen for now
● Production ready?
● Zero Javadoc or other
documentation
● Missing big picture
● Backend part needs to be
implemented first
● Ugly names for generics:
MutationPayload<User> =>
MutationPayload_User
● Hard to change smart
conventions
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
Schema is ready, what’s next?
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
How to implement DataFetcher for queries
GET /customers/2?fields=id,name,email,orders(id,status)
@Component
public class CustomerFetcher extends PropertyDataFetcher<Customer> {
@Autowired
private CustomerService customerService;
@Override
public Customer get(DataFetchingEnvironment environment) {
String id = environment.getArgument("id");
return customerService.getCustomerById(id);
}
}
RE
ST
{
customer(id: "2") {
id
name
orders {
id
status
}
}
}
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
How to implement DataFetcher for queries
GET /customers/2?fields=id,name,email,orders(id,status)
public class Customer {
private String id;
private String name;
private String email; // getters are not required
}
RE
ST
{
customer(id: "2") {
id
name
orders {
id
status
}
}
}
public class OrderDataFetcher extends PropertyDataFetcher<List<Order>> {
@Override
public List<Order> get(DataFetchingEnvironment environment) {
Customer source = environment.getSource();
String customerId = source.getId();
return orderService.getOrdersByCustomerId(customerId);
}
}
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
How to implement DataFetcher for mutations
POST /customers PUT /customers/123 DELETE /customers/123 PATCH /customers/123
@Component
public class CreateCustomersFetcher extends
PropertyDataFetcher<CreateCustomersPayload> {
@Override
public CreateCustomerPayload get(DataFetchingEnvironment env) {
Map<String, Object> input = env.getArgument("input");
String name = (String) input.get("name");
String email = (String) input.get("email");
String clientMutationId = (String) input.get("clientMutationId");
Customer customer = customerService.create(name, email);
return new CreateCustomerPayload(customer, clientMutationId);
}
RE
ST
mutation {
createCustomer(input: {
name: "MyName"
email: "me@me.com"
clientMutationId: "123"
}) {
customer {
id
}
clientMutationId
}
}
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
In case Interfaces and Unions - Type Resolver is needed
public class UserTypeResolver implements TypeResolver {
@Override
public GraphQLObjectType getType(TypeResolutionEnvironment env) {
Object javaObject = env.getObject();
if (javaObject instanceof Admin) {
return env.getSchema().getObjectType("Admin");
} else if (javaObject instanceof Moderator) {
return env.getSchema().getObjectType("Moderator");
} else {
throw new RuntimeException("Unknown type " + javaObject.getClass().getName());
}
}
}
public interface User {...}
public class Admin implements User {...}
public class Moderator implements User {...}
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
Glue everything together
RuntimeWiring runtimeWiring = RuntimeWiring.newRuntimeWiring()
.type("Query", builder ->
builder.dataFetcher("customer", customerFetcher))
.type("Mutation", builder ->
builder.dataFetcher("createCustomer", createCustomerFetcher))
.type(newTypeWiring("User")
.typeResolver(new UserTypeResolver())
.build())
...
.build();
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
GraphQL - How to define pagination, filtering, sorting?
Pagination:
● before, after
● offset, limit
Filtering:
● filter(name: “Bob” email: “%@gmail.com”)
● filter: {
OR: [{
email: “%@gmail.com”
}]
}, name: “Bob”
}
Sorting:
● orderBy: ASC, DESC
● sort: NEWEST, IMPORTANCE
GraphQL is not full query language (in Math sense)
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
GraphQL downsides
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
GraphQL downsides: N+1 problem
{
customers { 1 call
id
name
orders { n calls
id
status
}
}
}
java-dataloader
● Add async BatchLoader
● Add caching
graphQL = GraphQL.newGraphQL(schema)
.queryExecutionStrategy(
new BatchedExecutionStrategy())
.build();
+ @Batched in DataFetcher#get()
New way: https://www.graphql-java.com/documentation/v16/batching/
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
Complex Queries
fragment Friends on Friend {
id
name
friends {
id
name
friends {
id
name
...
}
}
}
graphQL = GraphQL.newGraphQL(schema)
.instrumentation(
new ChainedInstrumentation(asList(
new MaxQueryComplexityInstrumentation(20),
new MaxQueryDepthInstrumentation(2)
)))
.build();
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
GraphQL downsides: Bad GraphQL API definition - examples
{
customer(id: "2") { … }
customerFull(id: "2") { … }
customerFull2(id: "2") { … }
customerWithDetails(id: "2") { … }
...
}
{
customer(id: "2") {
id
name
orders {
id
status
}
}
}
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
GraphQL downsides: Bad GraphQL API definition - examples
{
orders (input: {
status: "NEW"
first: "2"
offset: "3"
}, first: "1", offset: "3") {
Items { … }
}
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
GraphQL downsides: Bad GraphQL API definition - examples
Relay Cursor Connections Specification section 5 (PageInfo)
type PageInfo {
hasNextPage: Boolean
}
type PageInfo {
hasNextPage: Boolean!
hasPreviousPage: Boolean!
}
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
GraphQL schema validation
https://github.com/cjoudrey/graphql-schema-linter
Validate GraphQL schema definitions against a set of rules
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
GraphQL Testing
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
Testing GraphQL
@SpringBootTest
@ContextConfiguration(classes = Main)
class CustomerFetcherSpec extends Specification {
@Autowired
GraphQLSchema graphQLSchema
GraphQL graphQL
def setup() {
graphQL = GraphQL.newGraphQL(graphQLSchema).build()
}
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
Testing GraphQL
def "should get customer by id"() {
given:
def query = """{ customer(id: "2") { … } }"""
def expected = [ "customer": [ … ] ]
when:
def result = graphQL.execute(query)
then:
result.data == expected
}
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
Testing is easy
Trap Adventure 2 - "The Hardest Retro Game"
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
Versioning
GraphQL takes a strong opinion on avoiding
versioning by providing the tools for the
continuous evolution of a GraphQL schema.
Src: https://graphql.org/learn/best-practices/#versioning
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
Versioning
type Query {
customer(id: String!): Customer! @deprecated(reason: "not used ...")
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
Versioning
Versioning is not a problem
GET /v2/customers/111RE
ST
GET /customers/111?v=v2RE
ST
GET /customers/111 Accept header: application/vnd.myapp.2+jsonRE
ST
GET /customers/111 Custom header: x-ms-version:2RE
ST
Versioning problem is different
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
Tools
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
Tools GraphiQL
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
Tools Relay
user(...) {
photo(width: "120", height: "120")
}
user(...) {
name
}
user(...) {
email
}
user(...) {
name
email
photo(width: "120", height: "120")
}
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
GraphQL Java Tools
https://github.com/graphql-java/graphql-java-tools
Map GraphQL schema to POJOs
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
More libraries and projects related to graphql-java
https://github.com/graphql-java/awesome-graphql-java
● JPA Implementation of GraphQL (builds on graphql-java)
● And more examples
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
More libraries and projects related to graphql-java
https://github.com/Netflix/dgs-framework
● GraphQL Made Easy for Spring Boot
● Build a full-featured GraphQL server with Java or Kotlin in
record time
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
Apollo
Build a universal GraphQL API on top of your existing REST
APIs, so you can ship new application features fast without
waiting on backend changes.
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
Prisma.io
Building a GraphQL server with Prisma
● Solves N+1 Problem with built-in dataloader
● No boilerplate for CRUD, filters, pagination & more
● Easily implement GraphQL subscriptions
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
GraphQL Inspector
GraphQL Inspector outputs a list of changes between two
GraphQL schemas. Every change is precisely explained and
marked as breaking, non-breaking or dangerous.
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
Tooling
Tooling is nice now
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
Who is using GraphQL
● GitHub: https://docs.github.com/en/free-pro-team@latest/graphql
● Netflix about Federation:
https://netflixtechblog.com/how-netflix-scales-its-api-with-graphql-
federation-part-1-ae3557c187e2
● Shopify: https://shopify.dev/docs/admin-api/graphql/reference
@MarcinStachniuk@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
Good practices
● Create handy schema for frontend
● Always generate GraphQL Schema and commit into your repository
● Validate your schema
● Do not use classic code first or SPQR approach to define schema
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
Technology Radar - GraphQL
GraphQL
● APR 2016 ASSESS
● NOV 2016 ASSESS
● NOV 2019 ASSESS
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
Src: https://www.thoughtworks.com/radar/languages-and-frameworks/graphql
Technology Radar - GraphQL
… misuse of this framework [...] Examples include performance gotchas
around N+1 queries and lots of boilerplate code needed when adding new
models, leading to complexity. There are workarounds to these gotchas
such as query caching...
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
Src: https://www.thoughtworks.com/radar/languages-and-frameworks/graphql
Technology Radar - GraphQL for server-side resource aggregation
GraphQL for server-side resource aggregation
● MAY 2018 ASSESS
● MAY 2020 TRIAL
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
Src: https://www.thoughtworks.com/radar/techniques/graphql-for-server-side-resource-aggregation
Technology Radar - GraphQL for server-side resource aggregation
we caution against misusing GraphQL, especially when turning it into a
server-to-server protocol. Our practice is to use GraphQL for server-side
resource aggregation only.
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
Src: https://www.thoughtworks.com/radar/techniques/graphql-for-server-side-resource-aggregation
Summary
GraphQL Pros:
● Nice alternative to REST
● It can be used together with REST
● Good integration with Relay / ReactJS
● You get exactly what you want to get
● Good for API with different clients
● Good to use on top of existing API
● Self documented
● Easy testing
● Nice tooling
● Thin layer
GraphQL Cons:
● High entry barrier
● Hard to return simple Map
● Not well know (yet)
● Performance overhead
● A lot of similar code to write
● No Operation Idempotency
● No Cache & Security
● No Authorisation
● Always HTTP 200 -
unsupported tools
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
Take away
● https://stachniuk.com/talks/
● https://github.com/mstachniuk/graphql-java-example
● https://www.nurkiewicz.com/2019/10/graphql-server-in-java-part-i-basics.
html
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
GraphQL: The Documentary
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
https://www.youtube.com/watch?v=783ccP__No8
Nothing is a silver bullet
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
Q&A
@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
Thank you!

Mais conteúdo relacionado

Mais procurados

Domain Driven Design and Hexagonal Architecture with Rails
Domain Driven Design and Hexagonal Architecture with RailsDomain Driven Design and Hexagonal Architecture with Rails
Domain Driven Design and Hexagonal Architecture with RailsDeclan Whelan
 
Simplify Access to Data from Pivotal GemFire Using the GraphQL (G2QL) Extension
Simplify Access to Data from Pivotal GemFire Using the GraphQL (G2QL) ExtensionSimplify Access to Data from Pivotal GemFire Using the GraphQL (G2QL) Extension
Simplify Access to Data from Pivotal GemFire Using the GraphQL (G2QL) ExtensionVMware Tanzu
 
Html5 Interview Questions & Answers
Html5 Interview Questions & AnswersHtml5 Interview Questions & Answers
Html5 Interview Questions & AnswersRatnala Charan kumar
 
Finding the right stuff, an intro to Elasticsearch (at Rug::B)
Finding the right stuff, an intro to Elasticsearch (at Rug::B) Finding the right stuff, an intro to Elasticsearch (at Rug::B)
Finding the right stuff, an intro to Elasticsearch (at Rug::B) Michael Reinsch
 
Wcf data services
Wcf data servicesWcf data services
Wcf data servicesEyal Vardi
 
Grails Custom Tag lib
Grails Custom Tag libGrails Custom Tag lib
Grails Custom Tag libAli Tanwir
 
[DSBW Spring 2009] Unit 07: WebApp Design Patterns & Frameworks (3/3)
[DSBW Spring 2009] Unit 07: WebApp Design Patterns & Frameworks (3/3)[DSBW Spring 2009] Unit 07: WebApp Design Patterns & Frameworks (3/3)
[DSBW Spring 2009] Unit 07: WebApp Design Patterns & Frameworks (3/3)Carles Farré
 
Zensations Drupal 8 GraphQL Presentation 2015
Zensations Drupal 8 GraphQL Presentation 2015Zensations Drupal 8 GraphQL Presentation 2015
Zensations Drupal 8 GraphQL Presentation 2015Zensations GmbH
 
Typed? Dynamic? Both! Cross-platform DSLs in C#
Typed? Dynamic? Both! Cross-platform DSLs in C#Typed? Dynamic? Both! Cross-platform DSLs in C#
Typed? Dynamic? Both! Cross-platform DSLs in C#Vagif Abilov
 
Evolving The Java Language
Evolving The Java LanguageEvolving The Java Language
Evolving The Java LanguageQConLondon2008
 
Introduction to AJAX and DWR
Introduction to AJAX and DWRIntroduction to AJAX and DWR
Introduction to AJAX and DWRSweNz FixEd
 
Silverlight 2 for Developers - TechEd New Zealand 2008
Silverlight 2 for Developers - TechEd New Zealand 2008Silverlight 2 for Developers - TechEd New Zealand 2008
Silverlight 2 for Developers - TechEd New Zealand 2008Jonas Follesø
 
Grails Internationalization
Grails   InternationalizationGrails   Internationalization
Grails Internationalizationnakul-pant
 

Mais procurados (19)

Nativescript angular
Nativescript angularNativescript angular
Nativescript angular
 
Domain Driven Design and Hexagonal Architecture with Rails
Domain Driven Design and Hexagonal Architecture with RailsDomain Driven Design and Hexagonal Architecture with Rails
Domain Driven Design and Hexagonal Architecture with Rails
 
Simplify Access to Data from Pivotal GemFire Using the GraphQL (G2QL) Extension
Simplify Access to Data from Pivotal GemFire Using the GraphQL (G2QL) ExtensionSimplify Access to Data from Pivotal GemFire Using the GraphQL (G2QL) Extension
Simplify Access to Data from Pivotal GemFire Using the GraphQL (G2QL) Extension
 
Html5 Interview Questions & Answers
Html5 Interview Questions & AnswersHtml5 Interview Questions & Answers
Html5 Interview Questions & Answers
 
Finding the right stuff, an intro to Elasticsearch (at Rug::B)
Finding the right stuff, an intro to Elasticsearch (at Rug::B) Finding the right stuff, an intro to Elasticsearch (at Rug::B)
Finding the right stuff, an intro to Elasticsearch (at Rug::B)
 
Wcf data services
Wcf data servicesWcf data services
Wcf data services
 
Grails Custom Tag lib
Grails Custom Tag libGrails Custom Tag lib
Grails Custom Tag lib
 
[DSBW Spring 2009] Unit 07: WebApp Design Patterns & Frameworks (3/3)
[DSBW Spring 2009] Unit 07: WebApp Design Patterns & Frameworks (3/3)[DSBW Spring 2009] Unit 07: WebApp Design Patterns & Frameworks (3/3)
[DSBW Spring 2009] Unit 07: WebApp Design Patterns & Frameworks (3/3)
 
Zensations Drupal 8 GraphQL Presentation 2015
Zensations Drupal 8 GraphQL Presentation 2015Zensations Drupal 8 GraphQL Presentation 2015
Zensations Drupal 8 GraphQL Presentation 2015
 
Javascript
JavascriptJavascript
Javascript
 
Typed? Dynamic? Both! Cross-platform DSLs in C#
Typed? Dynamic? Both! Cross-platform DSLs in C#Typed? Dynamic? Both! Cross-platform DSLs in C#
Typed? Dynamic? Both! Cross-platform DSLs in C#
 
Java script -23jan2015
Java script -23jan2015Java script -23jan2015
Java script -23jan2015
 
Evolving The Java Language
Evolving The Java LanguageEvolving The Java Language
Evolving The Java Language
 
Introduction to AJAX and DWR
Introduction to AJAX and DWRIntroduction to AJAX and DWR
Introduction to AJAX and DWR
 
ajax_pdf
ajax_pdfajax_pdf
ajax_pdf
 
Enter the gradle
Enter the gradleEnter the gradle
Enter the gradle
 
Silverlight 2 for Developers - TechEd New Zealand 2008
Silverlight 2 for Developers - TechEd New Zealand 2008Silverlight 2 for Developers - TechEd New Zealand 2008
Silverlight 2 for Developers - TechEd New Zealand 2008
 
Grails Internationalization
Grails   InternationalizationGrails   Internationalization
Grails Internationalization
 
Capstone ms2
Capstone ms2Capstone ms2
Capstone ms2
 

Semelhante a GraphQL - Piękne API w Twojej Aplikacji - KrakowGraphAcademy

GraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learnedGraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learnedMarcinStachniuk
 
BruJUG Brussels GraphQL when RESR API is to less - lessons learned
BruJUG Brussels GraphQL when RESR API is to less - lessons learnedBruJUG Brussels GraphQL when RESR API is to less - lessons learned
BruJUG Brussels GraphQL when RESR API is to less - lessons learnedMarcinStachniuk
 
[DevCrowd] GraphQL - gdy API RESTowe to za mało
[DevCrowd] GraphQL - gdy API RESTowe to za mało[DevCrowd] GraphQL - gdy API RESTowe to za mało
[DevCrowd] GraphQL - gdy API RESTowe to za małoMarcinStachniuk
 
GraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learnedGraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learnedMarcinStachniuk
 
GraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learnedGraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learnedMarcinStachniuk
 
GraphQL and its schema as a universal layer for database access
GraphQL and its schema as a universal layer for database accessGraphQL and its schema as a universal layer for database access
GraphQL and its schema as a universal layer for database accessConnected Data World
 
GraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learnedGraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learnedMarcinStachniuk
 
GraphQL - gdy API RESTowe to za mało
GraphQL - gdy API RESTowe to za małoGraphQL - gdy API RESTowe to za mało
GraphQL - gdy API RESTowe to za małoMarcinStachniuk
 
GraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learnedGraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learnedMarcinStachniuk
 
GraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learnedGraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learnedMarcinStachniuk
 
GraphQL & Prisma from Scratch
GraphQL & Prisma from ScratchGraphQL & Prisma from Scratch
GraphQL & Prisma from ScratchNikolas Burk
 
GraphQL Meetup Bangkok 3.0
GraphQL Meetup Bangkok 3.0GraphQL Meetup Bangkok 3.0
GraphQL Meetup Bangkok 3.0Tobias Meixner
 
Wroclaw GraphQL - GraphQL in Java
Wroclaw GraphQL - GraphQL in JavaWroclaw GraphQL - GraphQL in Java
Wroclaw GraphQL - GraphQL in JavaMarcinStachniuk
 
What could go wrong with a GraphQL query and can OpenTelemetry help? KubeCon...
What could go wrong  with a GraphQL query and can OpenTelemetry help? KubeCon...What could go wrong  with a GraphQL query and can OpenTelemetry help? KubeCon...
What could go wrong with a GraphQL query and can OpenTelemetry help? KubeCon...SonjaChevre
 
Tutorial: Building a GraphQL API in PHP
Tutorial: Building a GraphQL API in PHPTutorial: Building a GraphQL API in PHP
Tutorial: Building a GraphQL API in PHPAndrew Rota
 
GraphQL - A query language to empower your API consumers (NDC Sydney 2017)
GraphQL - A query language to empower your API consumers (NDC Sydney 2017)GraphQL - A query language to empower your API consumers (NDC Sydney 2017)
GraphQL - A query language to empower your API consumers (NDC Sydney 2017)Rob Crowley
 
How to provide a GraphQL API - I want it that way
How to provide a GraphQL API - I want it that wayHow to provide a GraphQL API - I want it that way
How to provide a GraphQL API - I want it that wayQAware GmbH
 
GraphQL Schema Stitching with Prisma & Contentful
GraphQL Schema Stitching with Prisma & ContentfulGraphQL Schema Stitching with Prisma & Contentful
GraphQL Schema Stitching with Prisma & ContentfulNikolas Burk
 
Code-first GraphQL Server Development with Prisma
Code-first  GraphQL Server Development with PrismaCode-first  GraphQL Server Development with Prisma
Code-first GraphQL Server Development with PrismaNikolas Burk
 
REST API に疲れたあなたへ贈る GraphQL 入門
REST API に疲れたあなたへ贈る GraphQL 入門REST API に疲れたあなたへ贈る GraphQL 入門
REST API に疲れたあなたへ贈る GraphQL 入門Keisuke Tsukagoshi
 

Semelhante a GraphQL - Piękne API w Twojej Aplikacji - KrakowGraphAcademy (20)

GraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learnedGraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learned
 
BruJUG Brussels GraphQL when RESR API is to less - lessons learned
BruJUG Brussels GraphQL when RESR API is to less - lessons learnedBruJUG Brussels GraphQL when RESR API is to less - lessons learned
BruJUG Brussels GraphQL when RESR API is to less - lessons learned
 
[DevCrowd] GraphQL - gdy API RESTowe to za mało
[DevCrowd] GraphQL - gdy API RESTowe to za mało[DevCrowd] GraphQL - gdy API RESTowe to za mało
[DevCrowd] GraphQL - gdy API RESTowe to za mało
 
GraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learnedGraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learned
 
GraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learnedGraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learned
 
GraphQL and its schema as a universal layer for database access
GraphQL and its schema as a universal layer for database accessGraphQL and its schema as a universal layer for database access
GraphQL and its schema as a universal layer for database access
 
GraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learnedGraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learned
 
GraphQL - gdy API RESTowe to za mało
GraphQL - gdy API RESTowe to za małoGraphQL - gdy API RESTowe to za mało
GraphQL - gdy API RESTowe to za mało
 
GraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learnedGraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learned
 
GraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learnedGraphQL - when REST API is to less - lessons learned
GraphQL - when REST API is to less - lessons learned
 
GraphQL & Prisma from Scratch
GraphQL & Prisma from ScratchGraphQL & Prisma from Scratch
GraphQL & Prisma from Scratch
 
GraphQL Meetup Bangkok 3.0
GraphQL Meetup Bangkok 3.0GraphQL Meetup Bangkok 3.0
GraphQL Meetup Bangkok 3.0
 
Wroclaw GraphQL - GraphQL in Java
Wroclaw GraphQL - GraphQL in JavaWroclaw GraphQL - GraphQL in Java
Wroclaw GraphQL - GraphQL in Java
 
What could go wrong with a GraphQL query and can OpenTelemetry help? KubeCon...
What could go wrong  with a GraphQL query and can OpenTelemetry help? KubeCon...What could go wrong  with a GraphQL query and can OpenTelemetry help? KubeCon...
What could go wrong with a GraphQL query and can OpenTelemetry help? KubeCon...
 
Tutorial: Building a GraphQL API in PHP
Tutorial: Building a GraphQL API in PHPTutorial: Building a GraphQL API in PHP
Tutorial: Building a GraphQL API in PHP
 
GraphQL - A query language to empower your API consumers (NDC Sydney 2017)
GraphQL - A query language to empower your API consumers (NDC Sydney 2017)GraphQL - A query language to empower your API consumers (NDC Sydney 2017)
GraphQL - A query language to empower your API consumers (NDC Sydney 2017)
 
How to provide a GraphQL API - I want it that way
How to provide a GraphQL API - I want it that wayHow to provide a GraphQL API - I want it that way
How to provide a GraphQL API - I want it that way
 
GraphQL Schema Stitching with Prisma & Contentful
GraphQL Schema Stitching with Prisma & ContentfulGraphQL Schema Stitching with Prisma & Contentful
GraphQL Schema Stitching with Prisma & Contentful
 
Code-first GraphQL Server Development with Prisma
Code-first  GraphQL Server Development with PrismaCode-first  GraphQL Server Development with Prisma
Code-first GraphQL Server Development with Prisma
 
REST API に疲れたあなたへ贈る GraphQL 入門
REST API に疲れたあなたへ贈る GraphQL 入門REST API に疲れたあなたへ贈る GraphQL 入門
REST API に疲れたあなたへ贈る GraphQL 入門
 

Mais de MarcinStachniuk

[WroclawJUG] Continuous Delivery in OSS using Shipkit
[WroclawJUG] Continuous Delivery in OSS using Shipkit[WroclawJUG] Continuous Delivery in OSS using Shipkit
[WroclawJUG] Continuous Delivery in OSS using ShipkitMarcinStachniuk
 
Continuous Delivery in OSS using Shipkit.org
Continuous Delivery in OSS using Shipkit.orgContinuous Delivery in OSS using Shipkit.org
Continuous Delivery in OSS using Shipkit.orgMarcinStachniuk
 
Java Web Start – jak żyć z tą dziwną technologią
Java Web Start – jak żyć z tą dziwną technologiąJava Web Start – jak żyć z tą dziwną technologią
Java Web Start – jak żyć z tą dziwną technologiąMarcinStachniuk
 
Zarządzanie zmianami w schemacie relacyjnych baz danych
Zarządzanie zmianami w schemacie relacyjnych baz danychZarządzanie zmianami w schemacie relacyjnych baz danych
Zarządzanie zmianami w schemacie relacyjnych baz danychMarcinStachniuk
 
Inicjatywa NoSQL na przykładzie db4o
Inicjatywa NoSQL na przykładzie db4oInicjatywa NoSQL na przykładzie db4o
Inicjatywa NoSQL na przykładzie db4oMarcinStachniuk
 
Automatic mechanism data migration between relational and object database
Automatic mechanism data migration between relational and object databaseAutomatic mechanism data migration between relational and object database
Automatic mechanism data migration between relational and object databaseMarcinStachniuk
 
Zastosowanie obiektowych baz danych na przykładzie db4o
Zastosowanie obiektowych baz danych na przykładzie db4oZastosowanie obiektowych baz danych na przykładzie db4o
Zastosowanie obiektowych baz danych na przykładzie db4oMarcinStachniuk
 
Continuous Delivery w projekcie Open Source - Marcin Stachniuk - DevCrowd 2017
Continuous Delivery w projekcie Open Source - Marcin Stachniuk - DevCrowd 2017Continuous Delivery w projekcie Open Source - Marcin Stachniuk - DevCrowd 2017
Continuous Delivery w projekcie Open Source - Marcin Stachniuk - DevCrowd 2017MarcinStachniuk
 
Java Web Start czyli jak żyć z tą dziwną technologią? & Continuous Delivery w...
Java Web Start czyli jak żyć z tą dziwną technologią? & Continuous Delivery w...Java Web Start czyli jak żyć z tą dziwną technologią? & Continuous Delivery w...
Java Web Start czyli jak żyć z tą dziwną technologią? & Continuous Delivery w...MarcinStachniuk
 
Java Web Start czyli jak żyć z tą dziwną technologią & Continuous Delivery w ...
Java Web Start czyli jak żyć z tą dziwną technologią & Continuous Delivery w ...Java Web Start czyli jak żyć z tą dziwną technologią & Continuous Delivery w ...
Java Web Start czyli jak żyć z tą dziwną technologią & Continuous Delivery w ...MarcinStachniuk
 
Continuous delivery w projekcie open source - Marcin Stachniuk
Continuous delivery w projekcie open source - Marcin StachniukContinuous delivery w projekcie open source - Marcin Stachniuk
Continuous delivery w projekcie open source - Marcin StachniukMarcinStachniuk
 
Zarządzanie zamianami w relacyjnych bazach danych
Zarządzanie zamianami w relacyjnych bazach danychZarządzanie zamianami w relacyjnych bazach danych
Zarządzanie zamianami w relacyjnych bazach danychMarcinStachniuk
 
Nowości w Javie 8 okiem programisty
Nowości w Javie 8 okiem programistyNowości w Javie 8 okiem programisty
Nowości w Javie 8 okiem programistyMarcinStachniuk
 
Liquibase - Zarządzanie zmianami w relacyjnych bazach danych
Liquibase - Zarządzanie zmianami w relacyjnych bazach danychLiquibase - Zarządzanie zmianami w relacyjnych bazach danych
Liquibase - Zarządzanie zmianami w relacyjnych bazach danychMarcinStachniuk
 
Poznaj lepiej swoje srodowisko programistyczne i zwieksz swoja produktywnosc ...
Poznaj lepiej swoje srodowisko programistyczne i zwieksz swoja produktywnosc ...Poznaj lepiej swoje srodowisko programistyczne i zwieksz swoja produktywnosc ...
Poznaj lepiej swoje srodowisko programistyczne i zwieksz swoja produktywnosc ...MarcinStachniuk
 
Poznaj lepiej swoje srodowisko programistyczne i zwieksz swoja produktywnosc ...
Poznaj lepiej swoje srodowisko programistyczne i zwieksz swoja produktywnosc ...Poznaj lepiej swoje srodowisko programistyczne i zwieksz swoja produktywnosc ...
Poznaj lepiej swoje srodowisko programistyczne i zwieksz swoja produktywnosc ...MarcinStachniuk
 
Upieksz swoje testy! Testowanie jednostkowe dla sredniozaawansowanych.
Upieksz swoje testy! Testowanie jednostkowe dla sredniozaawansowanych.Upieksz swoje testy! Testowanie jednostkowe dla sredniozaawansowanych.
Upieksz swoje testy! Testowanie jednostkowe dla sredniozaawansowanych.MarcinStachniuk
 
Podstawy tworzenia gier w J2ME, dla początkujących adeptów sztuki programowania
Podstawy tworzenia gier w J2ME, dla początkujących adeptów sztuki programowaniaPodstawy tworzenia gier w J2ME, dla początkujących adeptów sztuki programowania
Podstawy tworzenia gier w J2ME, dla początkujących adeptów sztuki programowaniaMarcinStachniuk
 

Mais de MarcinStachniuk (19)

[WroclawJUG] Continuous Delivery in OSS using Shipkit
[WroclawJUG] Continuous Delivery in OSS using Shipkit[WroclawJUG] Continuous Delivery in OSS using Shipkit
[WroclawJUG] Continuous Delivery in OSS using Shipkit
 
Continuous Delivery in OSS using Shipkit.org
Continuous Delivery in OSS using Shipkit.orgContinuous Delivery in OSS using Shipkit.org
Continuous Delivery in OSS using Shipkit.org
 
Java Web Start – jak żyć z tą dziwną technologią
Java Web Start – jak żyć z tą dziwną technologiąJava Web Start – jak żyć z tą dziwną technologią
Java Web Start – jak żyć z tą dziwną technologią
 
Zarządzanie zmianami w schemacie relacyjnych baz danych
Zarządzanie zmianami w schemacie relacyjnych baz danychZarządzanie zmianami w schemacie relacyjnych baz danych
Zarządzanie zmianami w schemacie relacyjnych baz danych
 
Inicjatywa NoSQL na przykładzie db4o
Inicjatywa NoSQL na przykładzie db4oInicjatywa NoSQL na przykładzie db4o
Inicjatywa NoSQL na przykładzie db4o
 
Automatic mechanism data migration between relational and object database
Automatic mechanism data migration between relational and object databaseAutomatic mechanism data migration between relational and object database
Automatic mechanism data migration between relational and object database
 
Zastosowanie obiektowych baz danych na przykładzie db4o
Zastosowanie obiektowych baz danych na przykładzie db4oZastosowanie obiektowych baz danych na przykładzie db4o
Zastosowanie obiektowych baz danych na przykładzie db4o
 
Wprowadzenie do J2ME
Wprowadzenie do J2MEWprowadzenie do J2ME
Wprowadzenie do J2ME
 
Continuous Delivery w projekcie Open Source - Marcin Stachniuk - DevCrowd 2017
Continuous Delivery w projekcie Open Source - Marcin Stachniuk - DevCrowd 2017Continuous Delivery w projekcie Open Source - Marcin Stachniuk - DevCrowd 2017
Continuous Delivery w projekcie Open Source - Marcin Stachniuk - DevCrowd 2017
 
Java Web Start czyli jak żyć z tą dziwną technologią? & Continuous Delivery w...
Java Web Start czyli jak żyć z tą dziwną technologią? & Continuous Delivery w...Java Web Start czyli jak żyć z tą dziwną technologią? & Continuous Delivery w...
Java Web Start czyli jak żyć z tą dziwną technologią? & Continuous Delivery w...
 
Java Web Start czyli jak żyć z tą dziwną technologią & Continuous Delivery w ...
Java Web Start czyli jak żyć z tą dziwną technologią & Continuous Delivery w ...Java Web Start czyli jak żyć z tą dziwną technologią & Continuous Delivery w ...
Java Web Start czyli jak żyć z tą dziwną technologią & Continuous Delivery w ...
 
Continuous delivery w projekcie open source - Marcin Stachniuk
Continuous delivery w projekcie open source - Marcin StachniukContinuous delivery w projekcie open source - Marcin Stachniuk
Continuous delivery w projekcie open source - Marcin Stachniuk
 
Zarządzanie zamianami w relacyjnych bazach danych
Zarządzanie zamianami w relacyjnych bazach danychZarządzanie zamianami w relacyjnych bazach danych
Zarządzanie zamianami w relacyjnych bazach danych
 
Nowości w Javie 8 okiem programisty
Nowości w Javie 8 okiem programistyNowości w Javie 8 okiem programisty
Nowości w Javie 8 okiem programisty
 
Liquibase - Zarządzanie zmianami w relacyjnych bazach danych
Liquibase - Zarządzanie zmianami w relacyjnych bazach danychLiquibase - Zarządzanie zmianami w relacyjnych bazach danych
Liquibase - Zarządzanie zmianami w relacyjnych bazach danych
 
Poznaj lepiej swoje srodowisko programistyczne i zwieksz swoja produktywnosc ...
Poznaj lepiej swoje srodowisko programistyczne i zwieksz swoja produktywnosc ...Poznaj lepiej swoje srodowisko programistyczne i zwieksz swoja produktywnosc ...
Poznaj lepiej swoje srodowisko programistyczne i zwieksz swoja produktywnosc ...
 
Poznaj lepiej swoje srodowisko programistyczne i zwieksz swoja produktywnosc ...
Poznaj lepiej swoje srodowisko programistyczne i zwieksz swoja produktywnosc ...Poznaj lepiej swoje srodowisko programistyczne i zwieksz swoja produktywnosc ...
Poznaj lepiej swoje srodowisko programistyczne i zwieksz swoja produktywnosc ...
 
Upieksz swoje testy! Testowanie jednostkowe dla sredniozaawansowanych.
Upieksz swoje testy! Testowanie jednostkowe dla sredniozaawansowanych.Upieksz swoje testy! Testowanie jednostkowe dla sredniozaawansowanych.
Upieksz swoje testy! Testowanie jednostkowe dla sredniozaawansowanych.
 
Podstawy tworzenia gier w J2ME, dla początkujących adeptów sztuki programowania
Podstawy tworzenia gier w J2ME, dla początkujących adeptów sztuki programowaniaPodstawy tworzenia gier w J2ME, dla początkujących adeptów sztuki programowania
Podstawy tworzenia gier w J2ME, dla początkujących adeptów sztuki programowania
 

Último

MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...Jittipong Loespradit
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2
 
WSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - KeynoteWSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - KeynoteWSO2
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Bert Jan Schrijver
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2
 
tonesoftg
tonesoftgtonesoftg
tonesoftglanshi9
 
What Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationWhat Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationJuha-Pekka Tolvanen
 
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...chiefasafspells
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnAmarnathKambale
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...Health
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...masabamasaba
 
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park masabamasaba
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrandmasabamasaba
 
%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in sowetomasabamasaba
 
WSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaSWSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaSWSO2
 
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open SourceWSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open SourceWSO2
 
Artyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxArtyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxAnnaArtyushina1
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park masabamasaba
 

Último (20)

MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
 
WSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - KeynoteWSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - Keynote
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 
tonesoftg
tonesoftgtonesoftg
tonesoftg
 
What Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationWhat Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the Situation
 
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
 
%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto
 
WSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaSWSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaS
 
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open SourceWSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
 
Artyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxArtyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptx
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 

GraphQL - Piękne API w Twojej Aplikacji - KrakowGraphAcademy

  • 1.
  • 3. What is NOT GraphQL GraphQL =/= Graph (math) GraphQL =/= GQL Standard GraphQL =/= openCypher, PGQL, GSQL, and G-CORE GraphQL =/= DQL (GraphQL+-) in Dgraph @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 4. What is GraphQL GraphQL == language for API @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 5. Who is using REST? @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 6. REST - REpresentational State Transfer https://api.example.com/customers/123 DELETE PUT POST GET PATCH @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 7. Issues with REST @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 8. Different clients - different needs Application Web iPhone Android TV Independent deploym ent @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 9. REST fixed response GET /customers/111 { "customer": { "id": "111", "name": "John Doe", "email": "john@doe.com", "company": { "id": "222" }, "orders": [ { "id": "333" }, { "id": "444" } ] } } { "customer": { "id": "111", "name": "John Doe", "email": "john@doe.com", "company": { "href": "https://api.example.com/companies/222" }, "orders": [ { "href": "https://api.example.com/orders/333" }, { "href": "https://api.example.com/orders/444" } ] } } RE ST Easy selectw hat you need @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 10. REST consequences: several roundtrips U nderFetching @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 11. REST response with nested data GET /customers/111 { "customer": { "id": "111", "name": "John Doe", "email": "john@doe.com", "company": { "id": "222", "name": "My Awesome Corporation", "website": "MyAwesomeCorporation.com" }, "orders": [ { "id": "333", "status": "delivered", "items": [ { "id": "555", "name": "Silver Bullet", "amount": "42", "price": "10000000", "currency": "USD", "producer": { "id": "777", "name": "Lorem Ipsum", "website": "LoremIpsum.com" } } ] }, { "id": "444", "name": "Golden Hammer", "amount": "5", "price": "10000", "currency": "USD", "producer": { ... } } ] } } RE ST O verFetching @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 12. REST API Versioning GET /v2/customers/111RE ST GET /customers/111?v=v2RE ST GET /customers/111 Accept header: application/vnd.myapp.2+jsonRE ST GET /customers/111 Custom header: x-ms-version:2RE ST A PIversioning @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 13. REST API as independent resources GET /customersRE ST GET /usersRE ST GET /ordersRE ST GET /itemsRE ST RE ST GET /companies D istorted reality @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 14. Platform Architecture - How to define a good API? Platform App 1 App 2 Customer App X... G ood A PIforall @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 15. GraphQL ● Graph Query Language ● Published by Facebook in 2015 ● Growth from Facebook Graph API ● Reference implementation in JavaScript ● First version of Java Library: 18 Jul 2015 https://github.com/graphql-java/graphql-java @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 16. GraphQL main concepts ● One endpoint for all operations ● Always define in request what you need ● Queries, Mutations and Subscriptions ● Defined by schema @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 17. Data is a graph @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 18. GraphQL time for demo ● Fragments ● Aliases ● Directives ● Interfaces ● Unions ● Query ● Syntax Error ● Mutation ● Operation name ● Variables @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 19. GraphQL Simple API GET /customers/2?fields=id,name,email type Customer { #fields with ! are not null id: ID! name: String! email: String! } type Query { customer(id: String!): Customer! } { "data": { "customer": { "id": "2", "name": "name", "email": "a@b.com" } } } { customer(id: "2") { id name email } } RE ST @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 20. GraphQL Bad Request GET /custo!@#$ -> 404 { "data": null, "errors": [ { "message": "Invalid Syntax", "locations": [ { "line": 2, "column": 8 } ], "errorType": "InvalidSyntax", "path": null, "extensions": null } ] } { custo!@#$ } RE ST http.cat/200 @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 21. Go back to the roots @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 22. GraphQL Simple API GET /customers/2?fields=id,name,email,company(id,name) type Customer { id: ID! name: String! email: String! company: Company } type Company { id: ID! name: String! website: String! } type Query { customer(id: String!): Customer! } { "data": { "customer": { "id": "2", "name": "name", "email": "a@b.com", "company": { "id": "211", "name": "Company Corp." } } } } { customer(id: "2") { id name email company { id name } } } RE ST @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 23. GraphQL Simple API GET /customers/2?fields=id,name,email,orders(id,status) type Customer { id: ID! name: String! email: String! company: Company orders: [Order] } type Order { id: ID! status: Status } enum Status { NEW, CANCELED, DONE } { "data": { "customer": { "id": "2", "name": "name", "orders": [ { "id": "55", "status": "NEW" }, { "id": "66", "status": "DONE" } ] } } } { customer(id: "2") { id name orders { id status } } } RE ST @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 24. GraphQL Aliases GET /customers/2?fields=id,name,email + { "data": { "cust1": { "id": "2", "name": "name", "email": "a@b.com" }, "cust2": { "id": "3", "name": "John Doe", "email": "john@doe.com" } } } query get2Cust { cust1: customer(id: "2") { id name email } cust2: customer(id: "3") { id name email } } RE ST GET /customers/3?fields=id,name,emailRE ST @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 25. GraphQL Fragment GET /customers/2?fields=id,name,email + { "data": { "cust1": { "id": "2", "name": "name", "email": "a@b.com" }, "cust2": { "id": "3", "name": "John Doe", "email": "john@doe.com" } } } query get2Cust { cust1: customer(id: "2") { ... frag1 } cust2: customer(id: "3") { ... frag1 } } fragment frag1 on Customer { id name email } RE ST GET /customers/3?fields=id,name,emailRE ST @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 26. GraphQL Arguments GET /customers/2?fields=id,name,email + { "data": { "cust1": { "id": "2", "name": "name", "email": "a@b.com" }, "cust2": { "id": "3", "name": "John Doe", "email": "john@doe.com" } } } query get2Cust($arg1:String!, $arg2: String!) { cust2: customer(id: $arg1) { ... frag1 } cust3: customer(id: $arg2) { ... frag1 } } fragment frag1 on Customer { id name email } RE ST GET /customers/3?fields=id,name,emailRE ST @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 27. GraphQL Directive GET /customers/2?fields=id,name { "data": { "customer": { "id": "2", "name": "name" } } } query getCust ($showEmail: Boolean!) { customer(id: "2") { id name email @include(if: $showEmail) } } { "showEmail": false } RE ST @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 28. GraphQL Interface GET /users?fields=id,name,superAdmin,permissions type Query { users: [User] } interface User { id: ID! name: String! email: String! } type Admin implements User { superAdmin: Boolean! // + id... } type Moderator implements User { permissions: [String] // + id... } { "data": { "users": [ { "id": "777", "name": "Admin a", "superAdmin": true }, { "id": "888", "name": "Moderator", "permissions": [ "Delete Customer", "Delete comment" ]}]}} query getUsers { users { ... on Admin { id name superAdmin } ... on Moderator { id name permissions } } } RE ST @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 29. GraphQL Union GET /search?input=a?fields=typename,name type Query { search(input: String): [SearchResult] } union SearchResult = Customer | Admin | Moderator { "data": { "search": [ { "__typename": "Customer", "name": "name" }, { "__typename": "Admin", "name": "Admin a" }, { "__typename": "Moderator", "name": "Moderator" }]}} query searchSmth { search(input: "a") { __typename ... on Customer { name } ... on Admin { name } ... on Moderator { name } } } RE ST @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 30. GraphQL mutations input CreateCustomerInput { name: String email: String clientMutationId: String! } type CreateCustomerPayload { customer: Customer clientMutationId: String! } type Mutation { createCustomer(input: CreateCustomerInput): CreateCustomerPayload! } { "data": { "createCustomer": { "customer": { "id": "40", }, "clientMutationId": "123" } } } POST /customers PUT /customers/123 DELETE /customers/123 PATCH /customers/123 mutation { createCustomer(input: { name: "MyName" email: "me@me.com" clientMutationId: "123" }) { customer { id } clientMutationId } } RE ST @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 31. GraphQL mutations + operation name mutation crCust { createCustomer(input: { name: "MyName" email: "me@me.com" clientMutationId: "123" }) { customer { id } clientMutationId } } { "data": { "createCustomer": { "customer": { "id": "40", }, "clientMutationId": "123" } } } POST /customers PUT /customers/123 DELETE /customers/123 PATCH /customers/123RE ST mutation { createCustomer(input: { name: "MyName" email: "me@me.com" clientMutationId: "123" }) { customer { id } clientMutationId } } @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 32. GraphQL Variables { "data": { "createCustomer": { "customer": { "id": "40", }, "clientMutationId": "123" } } } POST /customers PUT /customers/123 DELETE /customers/123 PATCH /customers/123 mutation crCust { createCustomer(input: { name: "MyName" email: "me@me.com" clientMutationId: "123" }) { customer { id } clientMutationId } } RE ST mutation crCust ($input: CreateCustInput) { createCustomer(input: $input) { customer { id } clientMutationId } } { "input": { "name": "MyName 2", "email": "me2@me.com", "clientMutationId": "123" } } @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 33. GraphQL Java implementations How to implement GraphQL in Java? /graphql-java/graphql-java @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 34. GraphQL type system How to define your schema? @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 35. Code First approach / programmatically private GraphQLFieldDefinition customerDefinition() { return GraphQLFieldDefinition.newFieldDefinition() .name("customer") .argument(GraphQLArgument.newArgument() .name("id") .type(new GraphQLNonNull(GraphQLString))) .type(new GraphQLNonNull(GraphQLObjectType.newObject() .name("Customer") .field(GraphQLFieldDefinition.newFieldDefinition() .name("id") .description("fields with ! are not null") .type(new GraphQLNonNull(GraphQLID)) .build()) …. .build())) .dataFetcher(customerFetcher) .build(); } Schema First approach type Query { customer(id: String!): Customer! } type Customer { #fields with ! are not null id: ID! name: String! email: String! company: Company orders: [Order] } @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 36. Schema First approach type Customer { # fields with ! are required id: ID! name: String! email: String! company: Company orders: [Order] } *.graphqls SchemaParser schemaParser = new SchemaParser(); File file = // ... TypeDefinitionRegistry registry = schemaParser.parse(file); SchemaGenerator schemaGenerator = new SchemaGenerator(); RuntimeWiring runtimeWiring = RuntimeWiring.newRuntimeWiring() .type("Query", builder -> builder.dataFetcher("customer", customerFetcher)) // ... .build(); return schemaGenerator.makeExecutableSchema(registry, runtimeWiring); @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 37. GraphQL SPQR leangen/graphql-spqr @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 38. SPQR approach public class UserService { @GraphQLQuery(name = "user") public User getById(@GraphQLArgument(name = "id") Integer id) { //... } } public class User { //... @GraphQLQuery(name = "name", description = "A person's name") public String getName() { return name; } } @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 39. SPQR approach - Smart conventions @GraphQLType(name = "Item") public class SpqrItem { private String id; private int amount; // ... @GraphQLId @GraphQLNonNull @GraphQLQuery(name = "id", description = "Item id") public String getId() { return id; } public int getAmount() { return amount; } } // 'ID' type in schema, add 'implements Node' // add ! (non null) in schema // optional // add ! (non null) because it’s int @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 40. Classic Code First Approach Pros: ● Stable library ● Some Javadoc and documentation ● It was the only way at the beginning in Java to define a schema Cons: ● Hard to maintain ● Missing big picture ● Backend part needs to be implemented first ● One DataFetcher for one operation ● No possibility to mix with Schema First ● No easy way to migrate to Schema First or SPQR ● Javadoc could be better @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 41. Schema First Approach Pros: ● Easy to maintain ● Stable library ● Some Javadoc and documentation ● Easy DSL to understand and maintain ● Reduce boilerplate to write ● A possibility to split schema into more files ● Parallel development (frontend & backend) Cons: ● Possible mismatch between types in schema file and Java code ● Binding between operations defined in schema and DataFetcher's is needed ● One DataFetcher for one operation @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 42. SPQR Approach Pros: ● The author replied to Github issues quickly ● Reduce boilerplate to write ● No mismatch between Schema and Java code ● No binding between schema and DataFetchers is needed ● Smart conventions Cons: ● Development is frozen for now ● Production ready? ● Zero Javadoc or other documentation ● Missing big picture ● Backend part needs to be implemented first ● Ugly names for generics: MutationPayload<User> => MutationPayload_User ● Hard to change smart conventions @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 43. Schema is ready, what’s next? @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 44. How to implement DataFetcher for queries GET /customers/2?fields=id,name,email,orders(id,status) @Component public class CustomerFetcher extends PropertyDataFetcher<Customer> { @Autowired private CustomerService customerService; @Override public Customer get(DataFetchingEnvironment environment) { String id = environment.getArgument("id"); return customerService.getCustomerById(id); } } RE ST { customer(id: "2") { id name orders { id status } } } @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 45. How to implement DataFetcher for queries GET /customers/2?fields=id,name,email,orders(id,status) public class Customer { private String id; private String name; private String email; // getters are not required } RE ST { customer(id: "2") { id name orders { id status } } } public class OrderDataFetcher extends PropertyDataFetcher<List<Order>> { @Override public List<Order> get(DataFetchingEnvironment environment) { Customer source = environment.getSource(); String customerId = source.getId(); return orderService.getOrdersByCustomerId(customerId); } } @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 46. How to implement DataFetcher for mutations POST /customers PUT /customers/123 DELETE /customers/123 PATCH /customers/123 @Component public class CreateCustomersFetcher extends PropertyDataFetcher<CreateCustomersPayload> { @Override public CreateCustomerPayload get(DataFetchingEnvironment env) { Map<String, Object> input = env.getArgument("input"); String name = (String) input.get("name"); String email = (String) input.get("email"); String clientMutationId = (String) input.get("clientMutationId"); Customer customer = customerService.create(name, email); return new CreateCustomerPayload(customer, clientMutationId); } RE ST mutation { createCustomer(input: { name: "MyName" email: "me@me.com" clientMutationId: "123" }) { customer { id } clientMutationId } } @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 47. In case Interfaces and Unions - Type Resolver is needed public class UserTypeResolver implements TypeResolver { @Override public GraphQLObjectType getType(TypeResolutionEnvironment env) { Object javaObject = env.getObject(); if (javaObject instanceof Admin) { return env.getSchema().getObjectType("Admin"); } else if (javaObject instanceof Moderator) { return env.getSchema().getObjectType("Moderator"); } else { throw new RuntimeException("Unknown type " + javaObject.getClass().getName()); } } } public interface User {...} public class Admin implements User {...} public class Moderator implements User {...} @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 48. Glue everything together RuntimeWiring runtimeWiring = RuntimeWiring.newRuntimeWiring() .type("Query", builder -> builder.dataFetcher("customer", customerFetcher)) .type("Mutation", builder -> builder.dataFetcher("createCustomer", createCustomerFetcher)) .type(newTypeWiring("User") .typeResolver(new UserTypeResolver()) .build()) ... .build(); @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 49. GraphQL - How to define pagination, filtering, sorting? Pagination: ● before, after ● offset, limit Filtering: ● filter(name: “Bob” email: “%@gmail.com”) ● filter: { OR: [{ email: “%@gmail.com” }] }, name: “Bob” } Sorting: ● orderBy: ASC, DESC ● sort: NEWEST, IMPORTANCE GraphQL is not full query language (in Math sense) @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 50. GraphQL downsides @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 51. GraphQL downsides: N+1 problem { customers { 1 call id name orders { n calls id status } } } java-dataloader ● Add async BatchLoader ● Add caching graphQL = GraphQL.newGraphQL(schema) .queryExecutionStrategy( new BatchedExecutionStrategy()) .build(); + @Batched in DataFetcher#get() New way: https://www.graphql-java.com/documentation/v16/batching/ @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 52. Complex Queries fragment Friends on Friend { id name friends { id name friends { id name ... } } } graphQL = GraphQL.newGraphQL(schema) .instrumentation( new ChainedInstrumentation(asList( new MaxQueryComplexityInstrumentation(20), new MaxQueryDepthInstrumentation(2) ))) .build(); @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 53. GraphQL downsides: Bad GraphQL API definition - examples { customer(id: "2") { … } customerFull(id: "2") { … } customerFull2(id: "2") { … } customerWithDetails(id: "2") { … } ... } { customer(id: "2") { id name orders { id status } } } @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 54. GraphQL downsides: Bad GraphQL API definition - examples { orders (input: { status: "NEW" first: "2" offset: "3" }, first: "1", offset: "3") { Items { … } } @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 55. GraphQL downsides: Bad GraphQL API definition - examples Relay Cursor Connections Specification section 5 (PageInfo) type PageInfo { hasNextPage: Boolean } type PageInfo { hasNextPage: Boolean! hasPreviousPage: Boolean! } @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 56. GraphQL schema validation https://github.com/cjoudrey/graphql-schema-linter Validate GraphQL schema definitions against a set of rules @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 57. GraphQL Testing @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 58. Testing GraphQL @SpringBootTest @ContextConfiguration(classes = Main) class CustomerFetcherSpec extends Specification { @Autowired GraphQLSchema graphQLSchema GraphQL graphQL def setup() { graphQL = GraphQL.newGraphQL(graphQLSchema).build() } @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 59. Testing GraphQL def "should get customer by id"() { given: def query = """{ customer(id: "2") { … } }""" def expected = [ "customer": [ … ] ] when: def result = graphQL.execute(query) then: result.data == expected } @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 60. Testing is easy Trap Adventure 2 - "The Hardest Retro Game" @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 61. Versioning GraphQL takes a strong opinion on avoiding versioning by providing the tools for the continuous evolution of a GraphQL schema. Src: https://graphql.org/learn/best-practices/#versioning @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 62. Versioning type Query { customer(id: String!): Customer! @deprecated(reason: "not used ...") @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 63. Versioning Versioning is not a problem GET /v2/customers/111RE ST GET /customers/111?v=v2RE ST GET /customers/111 Accept header: application/vnd.myapp.2+jsonRE ST GET /customers/111 Custom header: x-ms-version:2RE ST Versioning problem is different @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 64. Tools @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 65. Tools GraphiQL @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 66. Tools Relay user(...) { photo(width: "120", height: "120") } user(...) { name } user(...) { email } user(...) { name email photo(width: "120", height: "120") } @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 67. GraphQL Java Tools https://github.com/graphql-java/graphql-java-tools Map GraphQL schema to POJOs @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 68. More libraries and projects related to graphql-java https://github.com/graphql-java/awesome-graphql-java ● JPA Implementation of GraphQL (builds on graphql-java) ● And more examples @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 69. More libraries and projects related to graphql-java https://github.com/Netflix/dgs-framework ● GraphQL Made Easy for Spring Boot ● Build a full-featured GraphQL server with Java or Kotlin in record time @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 70. Apollo Build a universal GraphQL API on top of your existing REST APIs, so you can ship new application features fast without waiting on backend changes. @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 71. Prisma.io Building a GraphQL server with Prisma ● Solves N+1 Problem with built-in dataloader ● No boilerplate for CRUD, filters, pagination & more ● Easily implement GraphQL subscriptions @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 72. GraphQL Inspector GraphQL Inspector outputs a list of changes between two GraphQL schemas. Every change is precisely explained and marked as breaking, non-breaking or dangerous. @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 73. Tooling Tooling is nice now @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 74. Who is using GraphQL ● GitHub: https://docs.github.com/en/free-pro-team@latest/graphql ● Netflix about Federation: https://netflixtechblog.com/how-netflix-scales-its-api-with-graphql- federation-part-1-ae3557c187e2 ● Shopify: https://shopify.dev/docs/admin-api/graphql/reference @MarcinStachniuk@MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 75. Good practices ● Create handy schema for frontend ● Always generate GraphQL Schema and commit into your repository ● Validate your schema ● Do not use classic code first or SPQR approach to define schema @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 76. Technology Radar - GraphQL GraphQL ● APR 2016 ASSESS ● NOV 2016 ASSESS ● NOV 2019 ASSESS @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy Src: https://www.thoughtworks.com/radar/languages-and-frameworks/graphql
  • 77. Technology Radar - GraphQL … misuse of this framework [...] Examples include performance gotchas around N+1 queries and lots of boilerplate code needed when adding new models, leading to complexity. There are workarounds to these gotchas such as query caching... @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy Src: https://www.thoughtworks.com/radar/languages-and-frameworks/graphql
  • 78. Technology Radar - GraphQL for server-side resource aggregation GraphQL for server-side resource aggregation ● MAY 2018 ASSESS ● MAY 2020 TRIAL @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy Src: https://www.thoughtworks.com/radar/techniques/graphql-for-server-side-resource-aggregation
  • 79. Technology Radar - GraphQL for server-side resource aggregation we caution against misusing GraphQL, especially when turning it into a server-to-server protocol. Our practice is to use GraphQL for server-side resource aggregation only. @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy Src: https://www.thoughtworks.com/radar/techniques/graphql-for-server-side-resource-aggregation
  • 80. Summary GraphQL Pros: ● Nice alternative to REST ● It can be used together with REST ● Good integration with Relay / ReactJS ● You get exactly what you want to get ● Good for API with different clients ● Good to use on top of existing API ● Self documented ● Easy testing ● Nice tooling ● Thin layer GraphQL Cons: ● High entry barrier ● Hard to return simple Map ● Not well know (yet) ● Performance overhead ● A lot of similar code to write ● No Operation Idempotency ● No Cache & Security ● No Authorisation ● Always HTTP 200 - unsupported tools @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 81. Take away ● https://stachniuk.com/talks/ ● https://github.com/mstachniuk/graphql-java-example ● https://www.nurkiewicz.com/2019/10/graphql-server-in-java-part-i-basics. html @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 82. GraphQL: The Documentary @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy https://www.youtube.com/watch?v=783ccP__No8
  • 83. Nothing is a silver bullet @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy
  • 84. Q&A @MarcinStachniukGraphQL - piękne API w Twojej aplikacjiKrakowGraphAcademy