GraphQL
REST war gestern
Jens Siebert (@jens_siebert)
WebMontag Kassel, 10. Dezember 2018
https://www.slideshare.net/JensSiebert1
REST ist super!
aber es hat so seine Probleme…
Probleme mit REST: Overfetching
https://swapi.co/api/people/1/
{
"name": "Luke Skywalker",
"height": "172",
"mass": "77",
"hair_color": "blond",
"skin_color": "fair",
"eye_color": "blue",
"birth_year": "19BBY",
"gender": "male",
"homeworld": "https://swapi.co/api/planets/1/",
"films": [
"https://swapi.co/api/films/2/",
"https://swapi.co/api/films/6/",
"https://swapi.co/api/films/3/",
"https://swapi.co/api/films/1/",
"https://swapi.co/api/films/7/"
],
"species": [
"https://swapi.co/api/species/1/"
],
"vehicles": [
"https://swapi.co/api/vehicles/14/",
"https://swapi.co/api/vehicles/30/“
],
"starships": [
"https://swapi.co/api/starships/12/",
"https://swapi.co/api/starships/22/"
],
"created": "2014-12-09T13:50:51.644000Z",
"edited": "2014-12-20T21:17:56.891000Z",
"url": "https://swapi.co/api/people/1/"
}
Probleme mit REST: Underfetching
https://swapi.co/api/people/1/
{
"name": "Luke Skywalker",
"height": "172",
"mass": "77",
"hair_color": "blond",
"skin_color": "fair",
"eye_color": "blue",
"birth_year": "19BBY",
"gender": "male",
"homeworld": "https://swapi.co/api/planets/1/",
"films": [
"https://swapi.co/api/films/2/",
"https://swapi.co/api/films/6/",
"https://swapi.co/api/films/3/",
"https://swapi.co/api/films/1/",
"https://swapi.co/api/films/7/"
], …
https://swapi.co/api/films/3/
{
"title": "Return of the Jedi",
"episode_id": 6,
"opening_crawl": "Luke Skywalker has...",
"director": "Richard Marquand",
"producer": "Howard G. Kazanjian, George Lucas",
"release_date": "1983-05-25",
"characters": [
"https://swapi.co/api/people/1/",
"https://swapi.co/api/people/2/",
"https://swapi.co/api/people/3/",
"https://swapi.co/api/people/4/",
"https://swapi.co/api/people/5/",
"https://swapi.co/api/people/10/",
"https://swapi.co/api/people/13/",
…
Probleme mit REST: Endpoint Management
https://swapi.co/api/people
https://swapi.co/api/films
https://swapi.co/api/planets
https://swapi.co/api/starships
https://swapi.co/api/vehicles
https://swapi.co/api/characters-with-movie-title-and-director 🤢
GraphQL
• Kein Framework!
• Sprachspezifikation
• Deklarative Abfragesprache
• Deklarative Schema-Beschreibungssprache
• Beschreibt einen „Informationsgraph“ und die Abfragen darauf
• Implementierungen in verschiedenen Sprachen/Frameworks verfügbar
Lösung mit GraphQL: Overfetching
https://graphql.org/swapi-graphql
query {
person(personID: 1) {
name
height
gender
}
}
{
"data": {
"person": {
"name": "Luke Skywalker",
"height": 172,
"gender": "male"
}
}
}
Lösung mit GraphQL: Underfetching
https://graphql.org/swapi-graphql
query {
person(personID: 1) {
name
height
gender
filmConnection {
films {
title
director
}
}
}
}
{
"data": {
"person": {
"name": "Luke Skywalker",
"height": 172,
"gender": "male",
"filmConnection": {
"films": [
{
"title": "A New Hope",
"director": "George Lucas"
},…
Lösung mit GraphQL: Endpoint Management
https://graphql.org/swapi-graphql
Sprachelemente: Query
http://snowtooth.moonhighway.com
query {
allLifts {
id
name
status
}
}
{
"data": {
"allLifts": [
{
"id": "astra-express",
"name": "Astra Express",
"status": "OPEN"
},…
Sprachelemente: Query
http://snowtooth.moonhighway.com
query {
allLifts {
id
name
status
trailAccess {
name
status
}
}
}
{
"data": {
"allLifts": [
{
"id": "astra-express",
"name": "Astra Express",
"status": "OPEN",
"trailAccess": [
{
"name": "Blue Bird",
"status": "OPEN"
},…
Kante im Graph
Sprachelemente: Mutation
http://snowtooth.moonhighway.com
mutation {
setLiftStatus(id: "astra-express", status: CLOSED) {
id
name
status
}
}
{
"data": {
"setLiftStatus": {
"id": "astra-express",
"name": "Astra Express",
"status": "CLOSED"
}
}
}
Sprachelemente: Subscription
http://snowtooth.moonhighway.com
subscription {
liftStatusChange {
id
name
status
}
}
mutation {
setLiftStatus(id: "astra-express", status: CLOSED) {
id
name
status
}
}
{
"data": {
"liftStatusChange": {
"id": "astra-express",
"name": "Astra Express",
"status": “CLOSED"
}
}
}
OPEN -> CLOSED
Sprachelemente: Introspection
http://snowtooth.moonhighway.com
query {
__schema {
types {
name
kind
description
}
}
}
{
"data": {
"__schema": {
"types": [
{
"name": "Query",
"kind": "OBJECT",
"description": ""
},
{
"name": "LiftStatus",
"kind": "ENUM",
"description": "An enum describing …"
},
Sprachelemente: Typ-Definitionen
scalar DateTime
type Photo {
id: ID!
name: String!
url: String!
description: String
category: PhotoCategory!
postedBy: User!
taggedUsers: [User!]!
created: DateTime!
}
Basisdatentypen:
• ID
• Int
• Float
• String
• Boolean
Nullable Type
Non-Nullable Type
Custom Type
Non-Nullable List of Non-Nullable Type
Sprachelemente: Query/Mutations-Definition
type Query {
me: User
totalPhotos: Int!
allPhotos: [Photo!]!
Photo(id: ID!): Photo
totalUsers: Int!
allUsers: [User!]!
User(login: ID!): User
}
type Mutation {
postPhoto(input: PostPhotoInput!): Photo!
tagPhoto(githubLogin:ID! photoID:ID!): Photo!
…
}
Analog: Subscriptions
Implementierung: Type-Resolver
module.exports = {
Photo: {
id: parent => parent.id || parent._id,
url: parent => `/img/photos/${parent._id}.jpg`,
postedBy: (parent, args, { db }) => db.collection('users').findOne({ githubLogin: parent.userID }),
taggedUsers: async (parent, args, { db }) => {
const tags = await db.collection('tags').find().toArray()
const logins = tags
.filter(t => t.photoID === parent._id.toString())
.map(t => t.githubLogin)
return db.collection('users').find({ githubLogin: { $in: logins }}).toArray()
}
}, …
}
Implementierung: Query-Resolver
module.exports = {
me: (parent, args, { currentUser }) => currentUser,
totalPhotos: (parent, args, { db }) => db.collection('photos').estimatedDocumentCount(),
allPhotos: (parent, args, { db }) => db.collection('photos').find().toArray(),
Photo: (parent, args, { db }) => db.collection('photos').findOne({ _id: ObjectID(args.id) }),
totalUsers: (parent, args, { db }) => db.collection('users').estimatedDocumentCount(),
allUsers: (parent, args, { db }) => db.collection('users').find().toArray(),
User: (parent, args, { db }) => db.collection('users').findOne({ githubLogin: args.login })
}
Implementierung: Mutation-Resolver
async postPhoto(parent, args, { db, currentUser }) {
if (!currentUser) {
throw new Error('only an authorized user can post a photo').
}
const newPhoto = {
...args.input,
userID: currentUser.githubLogin,
created: new Date()
}
const { insertedIds } = await db.collection('photos').insert(newPhoto)
newPhoto.id = insertedIds[0]
return newPhoto
}
Implementierung: Server mit Apollo GraphQL
const resolvers = require('./resolvers')
const typeDefs = readFileSync('./typeDefs.graphql', 'UTF-8')
const server = new ApolloServer({
typeDefs,
resolvers,
context: async ({ req }) => {
…
}
})
Sicherheit
• Authorization
• Request Timeouts
• Data Limitation (Paging)
• Query Depth Limitation
• Query Complexity Limitation
• Monitoring
const depthLimit =
require('graphql-depth-limit')
const { createComplexityLimitRule } =
require('graphql-validation-complexity')
const server = new ApolloServer({
typeDefs,
resolvers,
validationRules: [
depthLimit(5),
createComplexityLimitRule(1000,
onCost: cost => console.log('query cost: ', cost))
],
context: async({ req, connection }) = > { ... }
})
Literatur
Vielen Dank!
https://graphql.org
https://graphql.org/learn
https://www.apollographql.com
Slides: https://www.slideshare.net/JensSiebert1
Code: https://github.com/moonhighway/learning-graphql
Beispiel: http://snowtooth.moonhighway.com
Twitter: @jens_siebert

More Related Content

PDF
Yql hacku iitd_2012
PPTX
Hacking up location aware apps
PDF
Cowboy development with Django
PPTX
You Either Surf Or You Fight
PDF
NoSQL & MongoDB
PDF
The Django Web Framework (EuroPython 2006)
PDF
Stack Overflow Austin - jQuery for Developers
PDF
Building Things Fast - and getting approval
Yql hacku iitd_2012
Hacking up location aware apps
Cowboy development with Django
You Either Surf Or You Fight
NoSQL & MongoDB
The Django Web Framework (EuroPython 2006)
Stack Overflow Austin - jQuery for Developers
Building Things Fast - and getting approval

What's hot (11)

PDF
Yahoo is open to developers
PDF
Swift Summit 2017: Server Swift State of the Union
PDF
Feed Normalization with Ember Data 1.0
PDF
실시간 웹 협업도구 만들기 V0.3
PDF
Performance and Optmization - a technical talk at Frontend London
PDF
Cheap tricks for startups
PPTX
Maintainable JavaScript 2012
PDF
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
PDF
分层语义化模板实践 ---- 张克军
PDF
RESTful API Design, Second Edition
PPTX
Unobtrusive javascript with jQuery
Yahoo is open to developers
Swift Summit 2017: Server Swift State of the Union
Feed Normalization with Ember Data 1.0
실시간 웹 협업도구 만들기 V0.3
Performance and Optmization - a technical talk at Frontend London
Cheap tricks for startups
Maintainable JavaScript 2012
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
分层语义化模板实践 ---- 张克军
RESTful API Design, Second Edition
Unobtrusive javascript with jQuery
Ad

Similar to GraphQL (20)

PDF
Grails for hipsters
PDF
The things browsers can do! SAE Alumni Convention 2014
PPTX
Introduction to the IIIF Image API
PDF
Great Developers Steal
PDF
Webapplikationen mit Backbone.js
PDF
Reactive Type safe Webcomponents with skateJS
PDF
JSON and the APInauts
PDF
HTML5 after the hype - JFokus2015
PPTX
The Flash Facebook Cookbook - FlashMidlands
PDF
JavaScript for Flex Devs
PDF
Quicli - From zero to a full CLI application in a few lines of Rust
PDF
Draw More, Work Less
PDF
Getting more out of Matplotlib with GR
PDF
How to Scrap Any Website's content using ScrapyTutorial of How to scrape (cra...
PDF
Leveraging the Power of Graph Databases in PHP
KEY
Async. and Realtime Geo Applications with Node.js
PDF
Art & music vs Google App Engine
PPT
Application Modeling with Graph Databases
PDF
前端MVC之BackboneJS
PDF
He stopped using for/while loops, you won't believe what happened next!
Grails for hipsters
The things browsers can do! SAE Alumni Convention 2014
Introduction to the IIIF Image API
Great Developers Steal
Webapplikationen mit Backbone.js
Reactive Type safe Webcomponents with skateJS
JSON and the APInauts
HTML5 after the hype - JFokus2015
The Flash Facebook Cookbook - FlashMidlands
JavaScript for Flex Devs
Quicli - From zero to a full CLI application in a few lines of Rust
Draw More, Work Less
Getting more out of Matplotlib with GR
How to Scrap Any Website's content using ScrapyTutorial of How to scrape (cra...
Leveraging the Power of Graph Databases in PHP
Async. and Realtime Geo Applications with Node.js
Art & music vs Google App Engine
Application Modeling with Graph Databases
前端MVC之BackboneJS
He stopped using for/while loops, you won't believe what happened next!
Ad

More from Jens Siebert (19)

PDF
WebAssembly
PDF
Embedded Rust
PDF
Embedded Rust
PPTX
Microservices mit Rust
PPTX
Backend-Services mit Rust
PPTX
TinyML – Machine Learning für eingebettete Systeme
PPTX
Deep Learning mit TensorFlow.js
PPTX
Chatbots bauen mit dem Microsoft Bot Framework
PPTX
Integrating The Things Network Applications with Azure IoT Services
PPTX
Embedded JavaScript
PPTX
Windows 10 IoT Core
PPTX
Microsoft Bot Framework (Node.js Edition)
PPTX
Microsoft Bot Framework (.NET Edition)
PPTX
Electron
PPTX
Windows 10 IoT Core
PPTX
Physical Web
PPTX
Windows 10 IoT Core
PPTX
TypeScript
PPTX
TypeScript
WebAssembly
Embedded Rust
Embedded Rust
Microservices mit Rust
Backend-Services mit Rust
TinyML – Machine Learning für eingebettete Systeme
Deep Learning mit TensorFlow.js
Chatbots bauen mit dem Microsoft Bot Framework
Integrating The Things Network Applications with Azure IoT Services
Embedded JavaScript
Windows 10 IoT Core
Microsoft Bot Framework (Node.js Edition)
Microsoft Bot Framework (.NET Edition)
Electron
Windows 10 IoT Core
Physical Web
Windows 10 IoT Core
TypeScript
TypeScript

Recently uploaded (20)

PDF
Microsoft Office 365 Crack Download Free
PDF
AI Guide for Business Growth - Arna Softech
PDF
AI/ML Infra Meetup | Beyond S3's Basics: Architecting for AI-Native Data Access
PPTX
MLforCyber_MLDataSetsandFeatures_Presentation.pptx
PPTX
Cybersecurity-and-Fraud-Protecting-Your-Digital-Life.pptx
PPTX
most interesting chapter in the world ppt
PDF
Website Design Services for Small Businesses.pdf
PDF
AI/ML Infra Meetup | LLM Agents and Implementation Challenges
PDF
Practical Indispensable Project Management Tips for Delivering Successful Exp...
PDF
Guide to Food Delivery App Development.pdf
PPTX
Trending Python Topics for Data Visualization in 2025
PDF
BoxLang Dynamic AWS Lambda - Japan Edition
PDF
Autodesk AutoCAD Crack Free Download 2025
PDF
DuckDuckGo Private Browser Premium APK for Android Crack Latest 2025
PDF
DNT Brochure 2025 – ISV Solutions @ D365
PDF
novaPDF Pro 11.9.482 Crack + License Key [Latest 2025]
PPTX
Introduction to Windows Operating System
PDF
EaseUS PDF Editor Pro 6.2.0.2 Crack with License Key 2025
PDF
E-Commerce Website Development Companyin india
PPTX
Matchmaking for JVMs: How to Pick the Perfect GC Partner
Microsoft Office 365 Crack Download Free
AI Guide for Business Growth - Arna Softech
AI/ML Infra Meetup | Beyond S3's Basics: Architecting for AI-Native Data Access
MLforCyber_MLDataSetsandFeatures_Presentation.pptx
Cybersecurity-and-Fraud-Protecting-Your-Digital-Life.pptx
most interesting chapter in the world ppt
Website Design Services for Small Businesses.pdf
AI/ML Infra Meetup | LLM Agents and Implementation Challenges
Practical Indispensable Project Management Tips for Delivering Successful Exp...
Guide to Food Delivery App Development.pdf
Trending Python Topics for Data Visualization in 2025
BoxLang Dynamic AWS Lambda - Japan Edition
Autodesk AutoCAD Crack Free Download 2025
DuckDuckGo Private Browser Premium APK for Android Crack Latest 2025
DNT Brochure 2025 – ISV Solutions @ D365
novaPDF Pro 11.9.482 Crack + License Key [Latest 2025]
Introduction to Windows Operating System
EaseUS PDF Editor Pro 6.2.0.2 Crack with License Key 2025
E-Commerce Website Development Companyin india
Matchmaking for JVMs: How to Pick the Perfect GC Partner

GraphQL

  • 1. GraphQL REST war gestern Jens Siebert (@jens_siebert) WebMontag Kassel, 10. Dezember 2018 https://www.slideshare.net/JensSiebert1
  • 2. REST ist super! aber es hat so seine Probleme…
  • 3. Probleme mit REST: Overfetching https://swapi.co/api/people/1/ { "name": "Luke Skywalker", "height": "172", "mass": "77", "hair_color": "blond", "skin_color": "fair", "eye_color": "blue", "birth_year": "19BBY", "gender": "male", "homeworld": "https://swapi.co/api/planets/1/", "films": [ "https://swapi.co/api/films/2/", "https://swapi.co/api/films/6/", "https://swapi.co/api/films/3/", "https://swapi.co/api/films/1/", "https://swapi.co/api/films/7/" ], "species": [ "https://swapi.co/api/species/1/" ], "vehicles": [ "https://swapi.co/api/vehicles/14/", "https://swapi.co/api/vehicles/30/“ ], "starships": [ "https://swapi.co/api/starships/12/", "https://swapi.co/api/starships/22/" ], "created": "2014-12-09T13:50:51.644000Z", "edited": "2014-12-20T21:17:56.891000Z", "url": "https://swapi.co/api/people/1/" }
  • 4. Probleme mit REST: Underfetching https://swapi.co/api/people/1/ { "name": "Luke Skywalker", "height": "172", "mass": "77", "hair_color": "blond", "skin_color": "fair", "eye_color": "blue", "birth_year": "19BBY", "gender": "male", "homeworld": "https://swapi.co/api/planets/1/", "films": [ "https://swapi.co/api/films/2/", "https://swapi.co/api/films/6/", "https://swapi.co/api/films/3/", "https://swapi.co/api/films/1/", "https://swapi.co/api/films/7/" ], … https://swapi.co/api/films/3/ { "title": "Return of the Jedi", "episode_id": 6, "opening_crawl": "Luke Skywalker has...", "director": "Richard Marquand", "producer": "Howard G. Kazanjian, George Lucas", "release_date": "1983-05-25", "characters": [ "https://swapi.co/api/people/1/", "https://swapi.co/api/people/2/", "https://swapi.co/api/people/3/", "https://swapi.co/api/people/4/", "https://swapi.co/api/people/5/", "https://swapi.co/api/people/10/", "https://swapi.co/api/people/13/", …
  • 5. Probleme mit REST: Endpoint Management https://swapi.co/api/people https://swapi.co/api/films https://swapi.co/api/planets https://swapi.co/api/starships https://swapi.co/api/vehicles https://swapi.co/api/characters-with-movie-title-and-director 🤢
  • 6. GraphQL • Kein Framework! • Sprachspezifikation • Deklarative Abfragesprache • Deklarative Schema-Beschreibungssprache • Beschreibt einen „Informationsgraph“ und die Abfragen darauf • Implementierungen in verschiedenen Sprachen/Frameworks verfügbar
  • 7. Lösung mit GraphQL: Overfetching https://graphql.org/swapi-graphql query { person(personID: 1) { name height gender } } { "data": { "person": { "name": "Luke Skywalker", "height": 172, "gender": "male" } } }
  • 8. Lösung mit GraphQL: Underfetching https://graphql.org/swapi-graphql query { person(personID: 1) { name height gender filmConnection { films { title director } } } } { "data": { "person": { "name": "Luke Skywalker", "height": 172, "gender": "male", "filmConnection": { "films": [ { "title": "A New Hope", "director": "George Lucas" },…
  • 9. Lösung mit GraphQL: Endpoint Management https://graphql.org/swapi-graphql
  • 10. Sprachelemente: Query http://snowtooth.moonhighway.com query { allLifts { id name status } } { "data": { "allLifts": [ { "id": "astra-express", "name": "Astra Express", "status": "OPEN" },…
  • 11. Sprachelemente: Query http://snowtooth.moonhighway.com query { allLifts { id name status trailAccess { name status } } } { "data": { "allLifts": [ { "id": "astra-express", "name": "Astra Express", "status": "OPEN", "trailAccess": [ { "name": "Blue Bird", "status": "OPEN" },… Kante im Graph
  • 12. Sprachelemente: Mutation http://snowtooth.moonhighway.com mutation { setLiftStatus(id: "astra-express", status: CLOSED) { id name status } } { "data": { "setLiftStatus": { "id": "astra-express", "name": "Astra Express", "status": "CLOSED" } } }
  • 13. Sprachelemente: Subscription http://snowtooth.moonhighway.com subscription { liftStatusChange { id name status } } mutation { setLiftStatus(id: "astra-express", status: CLOSED) { id name status } } { "data": { "liftStatusChange": { "id": "astra-express", "name": "Astra Express", "status": “CLOSED" } } } OPEN -> CLOSED
  • 14. Sprachelemente: Introspection http://snowtooth.moonhighway.com query { __schema { types { name kind description } } } { "data": { "__schema": { "types": [ { "name": "Query", "kind": "OBJECT", "description": "" }, { "name": "LiftStatus", "kind": "ENUM", "description": "An enum describing …" },
  • 15. Sprachelemente: Typ-Definitionen scalar DateTime type Photo { id: ID! name: String! url: String! description: String category: PhotoCategory! postedBy: User! taggedUsers: [User!]! created: DateTime! } Basisdatentypen: • ID • Int • Float • String • Boolean Nullable Type Non-Nullable Type Custom Type Non-Nullable List of Non-Nullable Type
  • 16. Sprachelemente: Query/Mutations-Definition type Query { me: User totalPhotos: Int! allPhotos: [Photo!]! Photo(id: ID!): Photo totalUsers: Int! allUsers: [User!]! User(login: ID!): User } type Mutation { postPhoto(input: PostPhotoInput!): Photo! tagPhoto(githubLogin:ID! photoID:ID!): Photo! … } Analog: Subscriptions
  • 17. Implementierung: Type-Resolver module.exports = { Photo: { id: parent => parent.id || parent._id, url: parent => `/img/photos/${parent._id}.jpg`, postedBy: (parent, args, { db }) => db.collection('users').findOne({ githubLogin: parent.userID }), taggedUsers: async (parent, args, { db }) => { const tags = await db.collection('tags').find().toArray() const logins = tags .filter(t => t.photoID === parent._id.toString()) .map(t => t.githubLogin) return db.collection('users').find({ githubLogin: { $in: logins }}).toArray() } }, … }
  • 18. Implementierung: Query-Resolver module.exports = { me: (parent, args, { currentUser }) => currentUser, totalPhotos: (parent, args, { db }) => db.collection('photos').estimatedDocumentCount(), allPhotos: (parent, args, { db }) => db.collection('photos').find().toArray(), Photo: (parent, args, { db }) => db.collection('photos').findOne({ _id: ObjectID(args.id) }), totalUsers: (parent, args, { db }) => db.collection('users').estimatedDocumentCount(), allUsers: (parent, args, { db }) => db.collection('users').find().toArray(), User: (parent, args, { db }) => db.collection('users').findOne({ githubLogin: args.login }) }
  • 19. Implementierung: Mutation-Resolver async postPhoto(parent, args, { db, currentUser }) { if (!currentUser) { throw new Error('only an authorized user can post a photo'). } const newPhoto = { ...args.input, userID: currentUser.githubLogin, created: new Date() } const { insertedIds } = await db.collection('photos').insert(newPhoto) newPhoto.id = insertedIds[0] return newPhoto }
  • 20. Implementierung: Server mit Apollo GraphQL const resolvers = require('./resolvers') const typeDefs = readFileSync('./typeDefs.graphql', 'UTF-8') const server = new ApolloServer({ typeDefs, resolvers, context: async ({ req }) => { … } })
  • 21. Sicherheit • Authorization • Request Timeouts • Data Limitation (Paging) • Query Depth Limitation • Query Complexity Limitation • Monitoring const depthLimit = require('graphql-depth-limit') const { createComplexityLimitRule } = require('graphql-validation-complexity') const server = new ApolloServer({ typeDefs, resolvers, validationRules: [ depthLimit(5), createComplexityLimitRule(1000, onCost: cost => console.log('query cost: ', cost)) ], context: async({ req, connection }) = > { ... } })
  • 23. Vielen Dank! https://graphql.org https://graphql.org/learn https://www.apollographql.com Slides: https://www.slideshare.net/JensSiebert1 Code: https://github.com/moonhighway/learning-graphql Beispiel: http://snowtooth.moonhighway.com Twitter: @jens_siebert

Editor's Notes

  • #7: Start: 2012 Initiale Version der Spezifikation und Referenzimplementierung: 2015 Production-Ready: 2016
  • #18: Parent => Eltern-Objekt => in diesem Fall ein Typ-Objekt