APIs The New Way
Volodymyr Tsukur @
API,
Volodymyr Tsukur
not DB!
Volodymyr Tsukur
Lead Engineer,
Dev Manager @
Partner @
EASYHUNT
Program Committee @
JEEConf, XP Days
flushdia vtsukur
Lithuania
Ukraine
Kyiv
Dnipro
Vilnius
Israel
Tel Aviv
Be’er Sheva
~ 115M+ users*
~ 700 engineers
~ 1800 employees
~ 500 microservices
title
price
images
description
info
...
{
}
GET /products/:id
imagesimages(1)
priceprice
titletitle
[
]
description
GET /products
...
info
{
}
10%!
OVER-fetching
01
GET /carts/:id
items [
{
product
quantity
total
}
{
}
]
subTotal
GET /carts/1
GET /products/59eb838e3f
GET /products/59eb88c400
GET /products/59eb838e40
- UNDER-fetching
- extra requests
02
GET /carts/1?projection=with-products
...
GET /carts/1?projection=summary
GET /carts/1?projection=
GET /carts/1?projection=
GET /carts/1?projection=with-products
- no unified & widely adopted
standard :( *
- harder to collaborate :(
03
How to @deprecate and
phase out outdated stuff?
04
2012
2015
β€œ... is a query language for APIs and a runtime for
fulfilling those queries with your existing data”
type User {
name: String
friends: [User]
city: City
}
type City {
name: String
population: Int
citizens: [User]
}
1. Define schema
{
user(name: String): User
...
}
2. Ask for data
user(name: String): User
2. Ask for data
{
user(name: β€œVanya Unicorn”) {
friends {
name
}
city {
name
population
}
}
}
3. Get it!
{
user(name: β€œVanya Unicorn”) {
friends {
name
}
city {
name
population
}
}
}
{
β€œdata”: {
β€œuser”: {
β€œfriends”: [
{ β€œname”: β€œLena” },
{ β€œname”: β€œStas” }
]
β€œcity”: {
β€œname”: β€œKyiv”,
β€œpopulation”: 2928087
}
}
}
}
only necessary data
{
β€œdata”: {
β€œuser”: {
β€œfriends”: [
{ β€œname”: β€œLena” },
{ β€œname”: β€œStas” }
]
β€œcity”: {
β€œname”: β€œKyiv”,
β€œpopulation”: 2928087
}
}
}
}
{
user(name: β€œVanya Unicorn”) {
friends {
name
}
city {
name
population
}
}
}
in one request *
{
β€œdata”: {
β€œuser”: {
β€œfriends”: [
{ β€œname”: β€œLena” },
{ β€œname”: β€œStas” }
]
β€œcity”: {
β€œname”: β€œKyiv”,
β€œpopulation”: 2928087
}
}
}
}
{
user(name: β€œVanya Unicorn”) {
friends {
name
}
city {
name
population
}
}
}
HTTP POST
let us see how it works!
WYSIWYG
efficient fetching
easier to develop
analytics
any data source and transport
graphql-java
HTTP
Cart Service
Product Service
let us rock and roll!
running query
{
cart(id: 1) {
items {
product {
title
price
images(limit: 1)
sku
}
quantity
total
}
subTotal
}
}
1)
{
cart(id: 1) {
items {
product {
title
price
images(limit: 1)
sku
}
quantity
total
}
subTotal
}
}
2) SELECT ... FROM Cart
INNER JOIN Item ...
{
cart(id: 1) {
items {
product {
title
price
images(limit: 1)
sku
}
quantity
total
}
subTotal
}
}
3)
+ n x
product {
title
price
images(limit: 1)
sku
}
product {
title
price
images(limit: 1)
sku
}
GET /products/1
GET /products/2
GET /products/3
e x p e c t a t i o n s
R
e
a
l
i
t
y
{
cart(id: 1) {
items {
product {
title
price
images(limit: 1)
sku
}
quantity
total
}
subTotal
}
}
+
GET /products?ids=1,2,3
@Batched
let’s fix it!
Security
{
user(name: β€œVanya Unicorn”) {
friends {
name
friends {
name
friends {
name
friends {
name
...
}
}
}
}
}
}
limit query depth
limit query complexity
let us defend!
throttling / rate limiting
set timeouts
pagination
schema {
query: Query
}
schema {
query: Query,
mutation: Mutation
}
type Mutation {
addProductToCart(cart: ID!,
product: ID!,
count: Int = 1): Cart
}
let us mutate!
+
+
I want it !!!
but let us see the BAD parts
caching
security
error handling
arbitrary resources / file uploads
operation idempotency?
operation naming
hypermedia
Java ecosystem
Alternatives
https://philsturgeon.uk/api/2017/01/24/graphql-vs-rest-overview/
https://blog.runscope.com/posts/you-might-not-need-graphql
NO !!!
but it shines
as an
integrated
solution
schema {
query: Query,
mutation: Mutation,
subscription: Subscription
}
type Subscription {
productAdded(cart: ID!): Cart
}
subscription {
productAdded(cart: 123) {
items {
product ...
}
subTotal
}
}
{
β€œdata”: {
β€œproductAdded”: {
β€œitems”: [
{ β€œproduct”: ... },
{ β€œproduct”: ... },
{ β€œproduct”: ... },
{ β€œproduct”: ... }
]
β€œsubTotal”: 289.33
}
}
}
://
{
β€œdata”: {
β€œproductAdded”: {
β€œitems”: [
{ β€œproduct”: ... },
{ β€œproduct”: ... },
{ β€œproduct”: ... },
{ β€œproduct”: ... }
]
β€œsubTotal”: 289.33
}
}
}
subscription {
productAdded(cart: 123) {
items {
product ...
}
subTotal
}
}
://
https://github.com/vtsukur/graphql-java-store
sample, not
production
ready code!
Questions?
volodymyrt@wix.com
flushdia vtsukur

GraphQL: APIs the New Way.