SlideShare a Scribd company logo
GraphQL
Consistency through code generation
by Aleksandr Obukhov
Aleksandr Obukhov
Lead Backend Engineer at AMBOSS GmbH
https://github.com/obukhov
@dclg_en
GraphQL
Consistency through code generation
by Aleksandr Obukhov
What is GraphQL?
Rise-your-hands game
Who is well versed with the GraphQL specification?
Who tried to implement GraphQL server with PHP?
Who is supporting GraphQL server in a production environment?
GraphQL
Server implementations are available for multiple languages, including Haskell,
JavaScript, Python, Ruby, Java, C#, Scala, Go, Elixir, Erlang, PHP, and Clojure
- API specification and runtime
- developed by Facebook
- published in 2015
RPC
API Interaction is just a remote
procedure call:
- It has “function name”
- It has arguments
- It has return value (response)
REST
All data is a resource:
- It can be created / read / updated /
deleted
- Resource is identified by URL
- It can be connected to another
resources through relation
Concepts of API
RPC REST
- Versioning of resource schema
- Limited set of operations with
resources
Limitations
- Versioning of endpoints and
response data
- Pre-designed structure of input
and output
Why do we like GraphQL?
Validation of input / output data
Tools: automatic documentation based on schema
Ready-to-be-used specification
Schema defines: data types, abstractions, relations
Operations defined by root Query/Mutation objects
All this can be found in other specifications
Why do we like GraphQL?
Query is disambiguous:
- no wildcard fields – you don’t need resource versions,
- type assertions, interfaces and unions – easy to extend with new types
Nice:
- built-in deprecation mechanism
Instead of implementing complete endpoints, developer defines the way to
resolve relations – easier to reuse code.
Schema definition language is simple and robust
Transport layer
How do we GraphQL?
webonyx/graphql-php
Request
Query
validation
Mapping to
resolvers
Assembling
result
Response
validation &
formatting
Response
Your app API layer
?
Global field resolver to resolve object properties
class DefaultFieldResolver
{
// ...
public function __invoke($source, $args, $context, ResolveInfo $info)
{
$fieldName = $info->fieldName;
$property = null;
if ($source instanceof TypeInterface) {
$method = 'get' . ucfirst($fieldName);
if (!method_exists($source, $method)) {
throw new FieldNotImplemented('Field <' . $fieldName . '> is not implemented for type <' . $info->parentType . '>');
}
$property = call_user_func_array([$source, $method], $args);
}
$fieldValue = $property instanceof Closure ? $property($source, $args, $context, $info) : $property;
return $fieldValue;
}
}
Adapters to represent API objectTypes
class TaxonomyType extends AbstractTaxonomyType
{
/** @var TaxonomyDTO */
private $taxonomy;
// ...
/** @return int */
public function getTreeDepth()
{
return $this->taxonomy->getTreeDepth();
}
/** @return TaxonType[] */
public function getTaxa()
{
return $this->dataLoaderRegistry->get('taxonByParentTaxon')->load($this->taxonomy->getRootTaxonId());
}
}
What are challenges there
Return values is up to your resolver implementation, but still duplicates schema
Resolvers receive validated data, but it is still presented as associative array
All inconsistencies can be spotted in the runtime only
Enum values needs to be duplicated
Input and output types field names needs to be duplicated
You define a set of resolver functions that implement application BL
GraphQL schema: code generation
Tom Landvoigt & Alex Obukhov
What schema defines
Input Object Type
Query Type Mutation Type
EnumInterface Object Type Unions
What schema defines
Input Object Type
input FeedbackInput {
message: String!
type: FeedbackType!
source: FeedbackSource!
}
Query Type
type Query {
user(eid: ID!): User
}
Mutation Type
type Mutation {
submitFeedback(feedback: FeedbackInput!): Boolean
}
Enum
enum Stage {
preclinic
clinic
doctor
}
Interface
interface Entity {
eid: ID!
}
Object Type
type User implements Entity {
eid: ID!
stage: Stage!
firstName: String
lastName: String
}
Code generation: Object Type
type User implements Entity {
eid: ID!
stage: Stage!
firstName: String
lastName: String
}
abstract class AbstractUserType implements EntityInterface
{
/** @return string */
abstract public function getEid();
/** @return string */
abstract public function getStage();
/** @return null|string */
abstract public function getFirstName();
/** @return null|string */
abstract public function getLastName();
}
Abstract class can be extended
by multiple different classes
Code generation: Object Type
class UserType extends AbstractUserType
{
private $user;
/** @return string */
public function getEid()
{
return $this->user->getUuid();
}
...
}
class AdminType extends AbstractUserType
{
private $admin;
/** @return string */
public function getEid()
{
return $this->admin>getExternalId();
}
...
}
Code generation: Interface
interface Entity {
eid: ID!
}
interface EntityInterface
{
/**
* @return string | int
*/
public function getEid();
}
Abstract class implements this
interface automatically
Code generation: Input Object Type
input FeedbackInput {
message: String!
type: FeedbackType!
source: FeedbackSource!
}
class FeedbackInputType
{
/** @var string */
private $message;
/** @var string */
private $type;
/** @var FeedbackSourceType */
private $source;
public function __construct(array $inputValues)
{
$this->message = $inputValues['message'];
$this->type = $inputValues['type'];
$this->source = new FeedbackSourceType(
$inputValues['source']
);
}
Input is wrapped to value object
recursively
Code generation: Enum
enum Stage {
preclinic
clinic
doctor
}
class StageEnum extends Enum
{
const PRECLINIC = 'preclinic';
const CLINIC = 'clinic';
const DOCTOR = 'doctor';
/** @inheritdoc */
public function getValues()
{
return [
self::PRECLINIC,
self::CLINIC,
self::DOCTOR,
];
}
}
Constants can be used to
guarantee the consistency
of schema via static analysis
Code generation: Union
union NodeContent = File | Folder
type Node {
eid: ID!
firstName: String
content: NodeContent
}
class NodeType extends AbstractNodeType
{
/** @return FileType|FolderType */
public function getContents()
{
...
}
}
Union definitions are used to
declare @return in the docblcok
Benefits
- Easier to kick-off new type – just extend and use IDE to create stubs
- Ready-to-be-used value objects for Enum and Input
- Automatic interfaces implementation
- Docblock support for types defined by schema
- Schema inconsistencies can be detected with static code analysis
Thank you! Questions?

More Related Content

What's hot

What You Need to Know about Lambdas
What You Need to Know about LambdasWhat You Need to Know about Lambdas
What You Need to Know about Lambdas
Ryan Knight
 
Php Chapter 2 3 Training
Php Chapter 2 3 TrainingPhp Chapter 2 3 Training
Php Chapter 2 3 Training
Chris Chubb
 
PHP Unit 3 functions_in_php_2
PHP Unit 3 functions_in_php_2PHP Unit 3 functions_in_php_2
PHP Unit 3 functions_in_php_2Kumar
 
Functional Programming in JavaScript
Functional Programming in JavaScriptFunctional Programming in JavaScript
Functional Programming in JavaScript
Will Livengood
 
Client sidescripting javascript
Client sidescripting javascriptClient sidescripting javascript
Client sidescripting javascript
Selvin Josy Bai Somu
 
Functional Javascript
Functional JavascriptFunctional Javascript
Functional Javascript
guest4d57e6
 
JavaScript Functions
JavaScript FunctionsJavaScript Functions
JavaScript Functions
Colin DeCarlo
 
Functional Principles for OO Developers
Functional Principles for OO DevelopersFunctional Principles for OO Developers
Functional Principles for OO Developers
jessitron
 
Function overloading and overriding
Function overloading and overridingFunction overloading and overriding
Function overloading and overriding
Rajab Ali
 
Class 3 - PHP Functions
Class 3 - PHP FunctionsClass 3 - PHP Functions
Class 3 - PHP Functions
Ahmed Swilam
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
Codemotion
 
Functions in c++
Functions in c++Functions in c++
Functions in c++
Maaz Hasan
 
Lecture 3 getting_started_with__c_
Lecture 3 getting_started_with__c_Lecture 3 getting_started_with__c_
Lecture 3 getting_started_with__c_
eShikshak
 
JavaScript - Chapter 9 - TypeConversion and Regular Expressions
 JavaScript - Chapter 9 - TypeConversion and Regular Expressions  JavaScript - Chapter 9 - TypeConversion and Regular Expressions
JavaScript - Chapter 9 - TypeConversion and Regular Expressions
WebStackAcademy
 
Function overloading
Function overloadingFunction overloading
Function overloading
Selvin Josy Bai Somu
 
Contracts in-clojure-pete
Contracts in-clojure-peteContracts in-clojure-pete
Contracts in-clojure-pete
jessitron
 
JavaScript For CSharp Developer
JavaScript For CSharp DeveloperJavaScript For CSharp Developer
JavaScript For CSharp Developer
Sarvesh Kushwaha
 
JavaScript - Chapter 6 - Basic Functions
 JavaScript - Chapter 6 - Basic Functions JavaScript - Chapter 6 - Basic Functions
JavaScript - Chapter 6 - Basic Functions
WebStackAcademy
 
Introduction to es6
Introduction to es6Introduction to es6
Introduction to es6
NexThoughts Technologies
 

What's hot (20)

What You Need to Know about Lambdas
What You Need to Know about LambdasWhat You Need to Know about Lambdas
What You Need to Know about Lambdas
 
Php Chapter 2 3 Training
Php Chapter 2 3 TrainingPhp Chapter 2 3 Training
Php Chapter 2 3 Training
 
PHP Unit 3 functions_in_php_2
PHP Unit 3 functions_in_php_2PHP Unit 3 functions_in_php_2
PHP Unit 3 functions_in_php_2
 
Functional Programming in JavaScript
Functional Programming in JavaScriptFunctional Programming in JavaScript
Functional Programming in JavaScript
 
JavaScript Core
JavaScript CoreJavaScript Core
JavaScript Core
 
Client sidescripting javascript
Client sidescripting javascriptClient sidescripting javascript
Client sidescripting javascript
 
Functional Javascript
Functional JavascriptFunctional Javascript
Functional Javascript
 
JavaScript Functions
JavaScript FunctionsJavaScript Functions
JavaScript Functions
 
Functional Principles for OO Developers
Functional Principles for OO DevelopersFunctional Principles for OO Developers
Functional Principles for OO Developers
 
Function overloading and overriding
Function overloading and overridingFunction overloading and overriding
Function overloading and overriding
 
Class 3 - PHP Functions
Class 3 - PHP FunctionsClass 3 - PHP Functions
Class 3 - PHP Functions
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
 
Functions in c++
Functions in c++Functions in c++
Functions in c++
 
Lecture 3 getting_started_with__c_
Lecture 3 getting_started_with__c_Lecture 3 getting_started_with__c_
Lecture 3 getting_started_with__c_
 
JavaScript - Chapter 9 - TypeConversion and Regular Expressions
 JavaScript - Chapter 9 - TypeConversion and Regular Expressions  JavaScript - Chapter 9 - TypeConversion and Regular Expressions
JavaScript - Chapter 9 - TypeConversion and Regular Expressions
 
Function overloading
Function overloadingFunction overloading
Function overloading
 
Contracts in-clojure-pete
Contracts in-clojure-peteContracts in-clojure-pete
Contracts in-clojure-pete
 
JavaScript For CSharp Developer
JavaScript For CSharp DeveloperJavaScript For CSharp Developer
JavaScript For CSharp Developer
 
JavaScript - Chapter 6 - Basic Functions
 JavaScript - Chapter 6 - Basic Functions JavaScript - Chapter 6 - Basic Functions
JavaScript - Chapter 6 - Basic Functions
 
Introduction to es6
Introduction to es6Introduction to es6
Introduction to es6
 

Similar to PHP: GraphQL consistency through code generation

Hexagonal architecture in PHP
Hexagonal architecture in PHPHexagonal architecture in PHP
Hexagonal architecture in PHP
Paulo Victor Gomes
 
Drupaljam xl 2019 presentation multilingualism makes better programmers
Drupaljam xl 2019 presentation   multilingualism makes better programmersDrupaljam xl 2019 presentation   multilingualism makes better programmers
Drupaljam xl 2019 presentation multilingualism makes better programmers
Alexander Varwijk
 
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
James Titcumb
 
Using the Windows 8 Runtime from C++
Using the Windows 8 Runtime from C++Using the Windows 8 Runtime from C++
Web2Day 2017 - Concilier DomainDriveDesign et API REST
Web2Day 2017 - Concilier DomainDriveDesign et API RESTWeb2Day 2017 - Concilier DomainDriveDesign et API REST
Web2Day 2017 - Concilier DomainDriveDesign et API REST
Nicolas Faugout
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5
Elena Kolevska
 
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
James Titcumb
 
What's New In Laravel 5
What's New In Laravel 5What's New In Laravel 5
What's New In Laravel 5
Darren Craig
 
Применение паттерна Page Object для автоматизации веб сервисов - новый взгляд
Применение паттерна Page Object для автоматизации веб сервисов - новый взглядПрименение паттерна Page Object для автоматизации веб сервисов - новый взгляд
Применение паттерна Page Object для автоматизации веб сервисов - новый взгляд
COMAQA.BY
 
How to code to code less
How to code to code lessHow to code to code less
How to code to code less
Anton Novikau
 
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
James Titcumb
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryTatsuhiko Miyagawa
 
Flask and Angular: An approach to build robust platforms
Flask and Angular:  An approach to build robust platformsFlask and Angular:  An approach to build robust platforms
Flask and Angular: An approach to build robust platforms
Ayush Sharma
 
PHP in one presentation
PHP in one presentationPHP in one presentation
PHP in one presentation
Milad Rahimi
 
Применение паттерна Page Object для автоматизации веб сервисов
Применение паттерна Page Object для автоматизации веб сервисовПрименение паттерна Page Object для автоматизации веб сервисов
Применение паттерна Page Object для автоматизации веб сервисов
COMAQA.BY
 
Creating native apps with WordPress
Creating native apps with WordPressCreating native apps with WordPress
Creating native apps with WordPress
Marko Heijnen
 
ClojureScript - Making Front-End development Fun again - John Stevenson - Cod...
ClojureScript - Making Front-End development Fun again - John Stevenson - Cod...ClojureScript - Making Front-End development Fun again - John Stevenson - Cod...
ClojureScript - Making Front-End development Fun again - John Stevenson - Cod...
Codemotion
 
Test-Driven Documentation for your REST(ful) service
Test-Driven Documentation for your REST(ful) serviceTest-Driven Documentation for your REST(ful) service
Test-Driven Documentation for your REST(ful) service
Jeroen Reijn
 
Building End to-End Web Apps Using TypeScript
Building End to-End Web Apps Using TypeScriptBuilding End to-End Web Apps Using TypeScript
Building End to-End Web Apps Using TypeScript
Gil Fink
 

Similar to PHP: GraphQL consistency through code generation (20)

Hexagonal architecture in PHP
Hexagonal architecture in PHPHexagonal architecture in PHP
Hexagonal architecture in PHP
 
Drupaljam xl 2019 presentation multilingualism makes better programmers
Drupaljam xl 2019 presentation   multilingualism makes better programmersDrupaljam xl 2019 presentation   multilingualism makes better programmers
Drupaljam xl 2019 presentation multilingualism makes better programmers
 
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
 
Using the Windows 8 Runtime from C++
Using the Windows 8 Runtime from C++Using the Windows 8 Runtime from C++
Using the Windows 8 Runtime from C++
 
Web2Day 2017 - Concilier DomainDriveDesign et API REST
Web2Day 2017 - Concilier DomainDriveDesign et API RESTWeb2Day 2017 - Concilier DomainDriveDesign et API REST
Web2Day 2017 - Concilier DomainDriveDesign et API REST
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5
 
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
 
What's New In Laravel 5
What's New In Laravel 5What's New In Laravel 5
What's New In Laravel 5
 
Применение паттерна Page Object для автоматизации веб сервисов - новый взгляд
Применение паттерна Page Object для автоматизации веб сервисов - новый взглядПрименение паттерна Page Object для автоматизации веб сервисов - новый взгляд
Применение паттерна Page Object для автоматизации веб сервисов - новый взгляд
 
OOP in PHP
OOP in PHPOOP in PHP
OOP in PHP
 
How to code to code less
How to code to code lessHow to code to code less
How to code to code less
 
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
 
Flask and Angular: An approach to build robust platforms
Flask and Angular:  An approach to build robust platformsFlask and Angular:  An approach to build robust platforms
Flask and Angular: An approach to build robust platforms
 
PHP in one presentation
PHP in one presentationPHP in one presentation
PHP in one presentation
 
Применение паттерна Page Object для автоматизации веб сервисов
Применение паттерна Page Object для автоматизации веб сервисовПрименение паттерна Page Object для автоматизации веб сервисов
Применение паттерна Page Object для автоматизации веб сервисов
 
Creating native apps with WordPress
Creating native apps with WordPressCreating native apps with WordPress
Creating native apps with WordPress
 
ClojureScript - Making Front-End development Fun again - John Stevenson - Cod...
ClojureScript - Making Front-End development Fun again - John Stevenson - Cod...ClojureScript - Making Front-End development Fun again - John Stevenson - Cod...
ClojureScript - Making Front-End development Fun again - John Stevenson - Cod...
 
Test-Driven Documentation for your REST(ful) service
Test-Driven Documentation for your REST(ful) serviceTest-Driven Documentation for your REST(ful) service
Test-Driven Documentation for your REST(ful) service
 
Building End to-End Web Apps Using TypeScript
Building End to-End Web Apps Using TypeScriptBuilding End to-End Web Apps Using TypeScript
Building End to-End Web Apps Using TypeScript
 

Recently uploaded

FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance
 
The Metaverse and AI: how can decision-makers harness the Metaverse for their...
The Metaverse and AI: how can decision-makers harness the Metaverse for their...The Metaverse and AI: how can decision-makers harness the Metaverse for their...
The Metaverse and AI: how can decision-makers harness the Metaverse for their...
Jen Stirrup
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance
 
Climate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing DaysClimate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing Days
Kari Kakkonen
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
Ana-Maria Mihalceanu
 
UiPath Community Day Dubai: AI at Work..
UiPath Community Day Dubai: AI at Work..UiPath Community Day Dubai: AI at Work..
UiPath Community Day Dubai: AI at Work..
UiPathCommunity
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
Thijs Feryn
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance
 
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdfObservability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Paige Cruz
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
Dorra BARTAGUIZ
 
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
SOFTTECHHUB
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
91mobiles
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
Laura Byrne
 
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
James Anderson
 
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptx
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptxSecstrike : Reverse Engineering & Pwnable tools for CTF.pptx
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptx
nkrafacyberclub
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
Ralf Eggert
 
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to ProductionGenerative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Aggregage
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Albert Hoitingh
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
OnBoard
 

Recently uploaded (20)

FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
 
The Metaverse and AI: how can decision-makers harness the Metaverse for their...
The Metaverse and AI: how can decision-makers harness the Metaverse for their...The Metaverse and AI: how can decision-makers harness the Metaverse for their...
The Metaverse and AI: how can decision-makers harness the Metaverse for their...
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
Climate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing DaysClimate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing Days
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
 
UiPath Community Day Dubai: AI at Work..
UiPath Community Day Dubai: AI at Work..UiPath Community Day Dubai: AI at Work..
UiPath Community Day Dubai: AI at Work..
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdfObservability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
 
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
 
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
 
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptx
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptxSecstrike : Reverse Engineering & Pwnable tools for CTF.pptx
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptx
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
 
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to ProductionGenerative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to Production
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
 

PHP: GraphQL consistency through code generation

  • 1. GraphQL Consistency through code generation by Aleksandr Obukhov
  • 2. Aleksandr Obukhov Lead Backend Engineer at AMBOSS GmbH https://github.com/obukhov @dclg_en
  • 3. GraphQL Consistency through code generation by Aleksandr Obukhov
  • 5. Rise-your-hands game Who is well versed with the GraphQL specification? Who tried to implement GraphQL server with PHP? Who is supporting GraphQL server in a production environment?
  • 6. GraphQL Server implementations are available for multiple languages, including Haskell, JavaScript, Python, Ruby, Java, C#, Scala, Go, Elixir, Erlang, PHP, and Clojure - API specification and runtime - developed by Facebook - published in 2015
  • 7. RPC API Interaction is just a remote procedure call: - It has “function name” - It has arguments - It has return value (response) REST All data is a resource: - It can be created / read / updated / deleted - Resource is identified by URL - It can be connected to another resources through relation Concepts of API
  • 8. RPC REST - Versioning of resource schema - Limited set of operations with resources Limitations - Versioning of endpoints and response data - Pre-designed structure of input and output
  • 9. Why do we like GraphQL? Validation of input / output data Tools: automatic documentation based on schema Ready-to-be-used specification Schema defines: data types, abstractions, relations Operations defined by root Query/Mutation objects All this can be found in other specifications
  • 10. Why do we like GraphQL? Query is disambiguous: - no wildcard fields – you don’t need resource versions, - type assertions, interfaces and unions – easy to extend with new types Nice: - built-in deprecation mechanism Instead of implementing complete endpoints, developer defines the way to resolve relations – easier to reuse code. Schema definition language is simple and robust
  • 11. Transport layer How do we GraphQL? webonyx/graphql-php Request Query validation Mapping to resolvers Assembling result Response validation & formatting Response Your app API layer ?
  • 12. Global field resolver to resolve object properties class DefaultFieldResolver { // ... public function __invoke($source, $args, $context, ResolveInfo $info) { $fieldName = $info->fieldName; $property = null; if ($source instanceof TypeInterface) { $method = 'get' . ucfirst($fieldName); if (!method_exists($source, $method)) { throw new FieldNotImplemented('Field <' . $fieldName . '> is not implemented for type <' . $info->parentType . '>'); } $property = call_user_func_array([$source, $method], $args); } $fieldValue = $property instanceof Closure ? $property($source, $args, $context, $info) : $property; return $fieldValue; } }
  • 13. Adapters to represent API objectTypes class TaxonomyType extends AbstractTaxonomyType { /** @var TaxonomyDTO */ private $taxonomy; // ... /** @return int */ public function getTreeDepth() { return $this->taxonomy->getTreeDepth(); } /** @return TaxonType[] */ public function getTaxa() { return $this->dataLoaderRegistry->get('taxonByParentTaxon')->load($this->taxonomy->getRootTaxonId()); } }
  • 14. What are challenges there Return values is up to your resolver implementation, but still duplicates schema Resolvers receive validated data, but it is still presented as associative array All inconsistencies can be spotted in the runtime only Enum values needs to be duplicated Input and output types field names needs to be duplicated You define a set of resolver functions that implement application BL
  • 15. GraphQL schema: code generation Tom Landvoigt & Alex Obukhov
  • 16. What schema defines Input Object Type Query Type Mutation Type EnumInterface Object Type Unions
  • 17. What schema defines Input Object Type input FeedbackInput { message: String! type: FeedbackType! source: FeedbackSource! } Query Type type Query { user(eid: ID!): User } Mutation Type type Mutation { submitFeedback(feedback: FeedbackInput!): Boolean } Enum enum Stage { preclinic clinic doctor } Interface interface Entity { eid: ID! } Object Type type User implements Entity { eid: ID! stage: Stage! firstName: String lastName: String }
  • 18. Code generation: Object Type type User implements Entity { eid: ID! stage: Stage! firstName: String lastName: String } abstract class AbstractUserType implements EntityInterface { /** @return string */ abstract public function getEid(); /** @return string */ abstract public function getStage(); /** @return null|string */ abstract public function getFirstName(); /** @return null|string */ abstract public function getLastName(); } Abstract class can be extended by multiple different classes
  • 19. Code generation: Object Type class UserType extends AbstractUserType { private $user; /** @return string */ public function getEid() { return $this->user->getUuid(); } ... } class AdminType extends AbstractUserType { private $admin; /** @return string */ public function getEid() { return $this->admin>getExternalId(); } ... }
  • 20. Code generation: Interface interface Entity { eid: ID! } interface EntityInterface { /** * @return string | int */ public function getEid(); } Abstract class implements this interface automatically
  • 21. Code generation: Input Object Type input FeedbackInput { message: String! type: FeedbackType! source: FeedbackSource! } class FeedbackInputType { /** @var string */ private $message; /** @var string */ private $type; /** @var FeedbackSourceType */ private $source; public function __construct(array $inputValues) { $this->message = $inputValues['message']; $this->type = $inputValues['type']; $this->source = new FeedbackSourceType( $inputValues['source'] ); } Input is wrapped to value object recursively
  • 22. Code generation: Enum enum Stage { preclinic clinic doctor } class StageEnum extends Enum { const PRECLINIC = 'preclinic'; const CLINIC = 'clinic'; const DOCTOR = 'doctor'; /** @inheritdoc */ public function getValues() { return [ self::PRECLINIC, self::CLINIC, self::DOCTOR, ]; } } Constants can be used to guarantee the consistency of schema via static analysis
  • 23. Code generation: Union union NodeContent = File | Folder type Node { eid: ID! firstName: String content: NodeContent } class NodeType extends AbstractNodeType { /** @return FileType|FolderType */ public function getContents() { ... } } Union definitions are used to declare @return in the docblcok
  • 24. Benefits - Easier to kick-off new type – just extend and use IDE to create stubs - Ready-to-be-used value objects for Enum and Input - Automatic interfaces implementation - Docblock support for types defined by schema - Schema inconsistencies can be detected with static code analysis