Queryable APIs
with MicroProfile GraphQL
Phillip Krüger
August 2020
@phillipkruger
Story
GraphQL
Spec
SmallRye
2
@phillipkruger
1.
Painting a picture
Giving you some context
3
@phillipkruger
BIG COMPANY
4
@phillipkruger
5
@phillipkruger
6
@phillipkruger
7
@phillipkruger
Legacy
It’s awesome ! Going to solve ALL our problems.
8
SOAP
FTP
RMI
REST
AS400
Java
@phillipkruger
9
@phillipkruger
Ladies and gentlemen: the story you are about to hear is true. Only the names have been changed to protect the innocent..
10
“
@phillipkruger
11
@GET
@Path("/{userId}")
public Profile getProfile(@PathParam("userId") int userId){
// Here find all data and return profile
}
Profile
id: Long
person: Person
scores: List<Scores>
Person
id: Long
surname: String
…..
names: String[]
Score
id: Long
type: ScoreType
value: ScoreValue
@phillipkruger
12
{
"id": 0,
"person": {
"addresses": [
{
"code": "86055-2543",
"lines": [
"20952 Warren Village",
"North Rodrick",
"New York",
"Croatia"
]
},
{
"code": "62300",
"lines": [
"49273 Ernser Wells",
"Kuhlmanfort",
"Georgia",
"Djibouti"
]
}
],
"biography": "Deleniti a ut unde perspiciatis qui est tempora. Velit asperiores et. Ex numquam quos reiciendis placeat vitae sint repudiandae.
Ratione molestiae delectus natus consequatur. Est a molestias nostrum rerum et odio blanditiis. Veritatis ducimus et consequatur modi.
Necessitatibus aut rerum. Distinctio debitis quidem eum beatae officiis.",
"birthDate": "27/10/1999",
"coverphotos": [
"http://lorempixel.com/g/1600/1200/business/"
],
"creditCards": [
{
"expiry": "2011-10-12",
"number": "1234-2121-1221-1211",
"type": "mastercard"
}
],
"emailAddresses": [
"missy.fritsch@gmail.com",
"chadwick.keebler@yahoo.com"
],
"favColor": "ivory",
"gender": "Female",
"id": 1,
"idNumber": "802-18-8226",
"imClients": [
{
"identifier": "Slack",
"im": "cole.waelchi"
},
{
"identifier": "ICQ",
"im": "barry.bergnaum"
}
],
"interests": [
"Overwatch",
"vinyl"
],
"joinDate": "24/09/2017",
"locale": "en-ZA",
"maritalStatus": "Divorced",
"names": [
"Alexandra",
"Leonia"
],
"nicknames": [
"Annie Moore"
],
"occupation": "Producer",
"organization": "Jerde-Kertzmann",
"phoneNumbers": [
{
"number": "158-692-8487",
"type": "Cell"
},
{
"number": "307.717.3673 x798",
"type": "Home"
},
{
"number": "1-833-310-6728",
"type": "Work"
}
],
"profilePictures": [
"https://s3.amazonaws.com/uifaces/faces/twitter/enda/128.jpg"
],
"relations": [
{
"personURI": "/rest/person/708",
"relationType": "Spouse"
}
],
"skills": [
"Networking skills",
"Fast learner"
],
"socialMedias": [
{
"name": "@florentino.bahringer",
"username": "Twitter"
},
{
"name": "ryan.christiansen",
"username": "Facebook"
}
],
"surname": "Gleichner",
"taglines": [
"The dark side clouds everything. Impossible to see the future is.",
"Chuck Norris burst the dot com bubble."
],
"title": "Miss",
"userAgent": "Opera/9.80 (X11; Linux i686; Ubuntu/14.10) Presto/2.12.388 Version/12.16",
"username": "nolan.roberts",
"websites": [
"http://www.burt-zieme.io",
"http://www.artie-windler.co"
]
},
"scores": [
{
"name": "Driving",
"value": 8
},
{
"name": "Fitness",
"value": 8
},
{
"name": "Activity",
"value": 77
},
{
"name": "Financial",
"value": 15
}
]
}
@phillipkruger
13
?
@phillipkruger
It’s awesome ! Going to solve ALL our problems.
14
HATEOAS
{
"id": "062-42-0952",
"person": "/rest/person/1",
"scores": "/rest/score/062-42-0952"
}
@phillipkruger
15
BFF
{
"id": 0,
"person": {
"addresses": [
{
"code": "86055-2543",
"lines": [
"20952 Warren Village",
"North Rodrick",
"New York",
"Croatia"
]
},
{
"code": "62300",
"lines": [
"49273 Ernser Wells",
"Kuhlmanfort",
"Georgia",
"Djibouti"
]
}
],
"biography": "Deleniti a ut unde perspiciatis qui est tempora. Velit asperiores et. Ex numquam quos reiciendis placeat vitae sint repudiandae.
Ratione molestiae delectus natus consequatur. Est a molestias nostrum rerum et odio blanditiis. Veritatis ducimus et consequatur modi.
Necessitatibus aut rerum. Distinctio debitis quidem eum beatae officiis.",
"birthDate": "27/10/1999",
"occupation": "Producer",
"organization": "Jerde-Kertzmann",
"phoneNumbers": [
{
"number": "158-692-8487",
"type": "Cell"
},
{
"number": "307.717.3673 x798",
"type": "Home"
},
{
"number": "1-833-310-6728",
"type": "Work"
}
],
"profilePictures": [
"https://s3.amazonaws.com/uifaces/faces/twitter/enda/128.jpg"
],
"relations": [
{
"personURI": "/rest/person/708",
"relationType": "Spouse"
}
],
"skills": [
"Networking skills",
@phillipkruger
@GET
@Path("/{userId}")
public Profile getProfile(@PathParam("userId") int userId){
// Here find all data and return profile
}
@GET
@Path("/lite/{userId}")
public ProfileLite getLiteProfile(@PathParam("userId") int userId){
// Here find some data and return profile
}
@phillipkruger
17
?
@phillipkruger
@GET
@Path("/{userId}")
public Profile getProfile(@PathParam("userId") int userId){
// Here find all data and return profile
}
@GET
@Path("/lite/{userId}")
public ProfileLite getLiteProfile(@PathParam("userId") int userId){
// Here find some data and return profile
}
@GET
@Path("/lite/status/{userId}")
public ProfileLiteWithStatus getLiteProfileWithStatus(@PathParam("userId") int userId){
// Here find some data (and the status) and return profile
}
@phillipkruger
@GET
@Path("/{userId}")
public Profile getProfile(@PathParam("userId") int userId){
// Here find all data and return profile
}
@GET
@Path("/{userId}")
public Profile getProfile(@PathParam("userId") int userId,
@QueryParam("include") String[] include,
@QueryParam("exclude") String[] exclude){
// Here find all data and return profile
}
@phillipkruger
Over-fetching is fetching too much data, aka there is data in the response you don't use.
Under-fetching is not having enough data with a call to an endpoint, leading you to call a second endpoint.
20
“
@phillipkruger
21
?
?
?
?
?
@phillipkruger
2.
Drawing board
Surely someone else have these issues ?
Back to the
22
@phillipkruger
Options
23
Queryable REST
@phillipkruger
GraphQL
It’s awesome ! Going to solve ALL our problems.
24
@phillipkruger
History
25
@phillipkruger
Some benefits
Data Fetching
No more Over- and Under Fetching
Development Speed
Rapid Product Iterations on the Frontend
Schema
Benefits of a Schema & Type System
26
@phillipkruger
27
Profile
GET: /rest/profile/5234
Person
GET: /rest/person/98763
Score
GET: /rest/score/A53FG5
REST
@phillipkruger
28
Profile
POST: /graphql
GraphQL
{
profile(personId: 1){
person{
names
surname
occupation
}
scores {
name
value
}
}
}
{
"data": {
"profile": {
"person": {
"names": [
"Sebastian",
"Jana"
],
"surname": "Heathcote",
"occupation": "Officer"
},
"scores": [
{
"name": "Driving",
"value": 78
}
]
}
}
}
@phillipkruger
29
Profile
POST: /graphql
GraphQL
{
profile(personId: 1) {
person{
title
surname
}
}
}
{
"data": {
"profile": {
"person": {
"title": "Mrs.",
"surname": "Heathcote"
}
}
}
}
@phillipkruger
30
GraphQL Concepts
Operations
Queries
Mutations
Subscription
Type
Input
Interface
Enum
Scalar
@phillipkruger
3.
Specification
Open source community specification for Enterprise Java
31
@phillipkruger
MicroProfile
Optimizing Enterprise Java for a Microservices Architecture
32
@phillipkruger
MicroProfile Process
sandbox
standalone
umbrella
@phillipkruger
MicroProfile Process
34
Spec
(Asciidoc)
API
(Java interfaces & Annotations)
TCK
(TestNG)
CI
(Java)
@phillipkruger
4.
Examples
Using SmallRye GraphQL
35
@phillipkruger
Known Implementations
36
SPQR
@phillipkruger
THANKS!
37
?
@phillipkruger
CREDITS
Special thanks to all the people who made and released these awesome resources for free:
38
@phillipkruger