SlideShare ist ein Scribd-Unternehmen logo
1 von 66
Downloaden Sie, um offline zu lesen
Contract first,
session types later
Marco Borst
::
vlsi -> java -> scala
Slava Schmidt
Play-Swagger plugin
@
Play-Swagger plugin
API-First single source of truth
code generation framework
=>
Specification
URLs
Verbs
Parameters
Security
Definitions Validations
Model
Test Data
Validations
Play Routes
Marshallers
Tests
Controllers
Security
Richardson Maturity Model
Level 0 - Wild Wild Web
Level 1 - Resources
Level 2 - HTTP Verbs
Level 3 - Hypermedia Controls
Level 2
of Richardson Maturity Model
Level 3
HATEOAS (Hypertext As The Engine Of Application State)
Specification
URLs
Verbs
Parameters
Definitions Mime-Types
Hypermedia
Controls
Server
Mime-Types
Hypermedia
Controls Client
Code
Client
Mime-Types
Hypermedia
Controls
Rules
Specification
Swagger RAML Apiary Blueprint
Spec formats
Swagger RAML Apiary Blueprint
Spec formats
Level 2 capable
Stateless REST communication
but
Stateful Resources
Stateful Clients
Stateful Sessions
Interacting state machines
Time
The arrows form a contract
between the server and its clients
Misbehaving state machines
Time
How to ensure right behaviour?
UBF - “who checks what goes over the wire”
UBF contract checker
Contract checker
CC
RS
AS
RS’
AS
RS’
AS’
S{HC} HC
HATEOAS
only allows us to check the
client behaviour
For the server we need
additional information
State
transitions
x-api-first-transitions:
packaged:
sending:
condition: Post is open
self:
sending:
moving:
condition: Accepted at the post
self:
moving:
delivering:
condition: Receiver is at home
lost:
self:
destroyed:
delivering:
delivered:
condition: Package undamaged
self:
lost:
moving:
State
transitions
UBF Session State
HATEOAS - State Locations
Contract checker
CC CC
RS
AS
RS’
AS
RS’
AS’
RS RS’ S{HC} HC
Contract checker is stateful
and
acts at runtime
Encode State => Type System
Runtime =>
Compile Time
Session types
session types do the same
for communication
as types do for data
http://groups.inf.ed.ac.uk/abcd/
Session types
codify structure
(communication, data)
and make it available to
programming tools
Scala Example
States
		sealed	trait	State	
		case	class	Packaged				(byWhom:							String)	extends	State	
		case	class	Sending						(whoAccepts:			String)	extends	State	
		case	class	Received				(whoDelivers:		String)	extends	State	
		case	class	Delivered			(toWhom:							String)	extends	State	
		case	class	Lost								(witness:						String)	extends	State	
		case	class	Moving						(tracking:					Long			)	extends	State	
		case	class	Destroyed			(when:			 	 	 				Long			)	extends	State
State Transitions
		sealed	abstract	class	~>[-A,+B]	
		implicit	case	object	GoToThePost			 	 	 	extends	~>[Packaged,Sending]	
		implicit	case	object	AcceptFromSender		 extends	~>[Sending,Moving]	
		implicit	case	object	BringToTheAddress		extends	~>[Moving,Received]	
		implicit	case	object	GiveToReceiver			 	extends	~>[Received,Delivered]	
		implicit	case	object	GetAngry			 	 	 	 	 	extends	~>[Moving,Destroyed]	
		implicit	case	object	DrinkAlcohol			 	 	extends	~>[Moving,Lost]	
		implicit	case	object	StopDrinking			 	 	extends	~>[Lost,Moving]
Resource
	case	class	Parcel[+S<:State](content:	Content,	receiver:	Receiver,	address:	Address)
Server part
			
def	server	=	
				In	{	p:	Parcel[Packaged]	=>	
						val	content	=	"Changed	by	server	"	+	p.content	
						val	result	=	Parcel[Sending](content,	p.receiver,	p.address)	
						val	stop	=	Stop("With	server	result:	"	+	result)	
						(stop,	result)	
				}
Client part
			
		def	client	=	{	
				val	parcel	=	Parcel[Packaged]("Content",	"Receiver",	"Address")	
				val	finish	=	Stop("With	client	result:	"	+	parcel)		
				Out(parcel,	finish)	
		}
Communication steps
	 	
		case	class	Stop(msg:	String)	
	 case	class	In	[R[S<:State],A<:State,B<:State,+C](recv:	R[A]	=>	(C,R[B]))	
(implicit	stateTransition:	~>[A,B])	
		case	class	Out[+R[S<:State],A<:State,+C](data:	R[A],	cont:	C)
Running Session
			
runSession(server,	client)
Session Runner
			
		trait	Session[S]	{	
				type	Self	=	S	
				type	Dual	
				type	DualOf[D]	=	Session[Self]	{	type	Dual	=	D	}	
				def	run	(self:	Self,	dual:	Dual):	Unit	
		}	
		
	def	runSession[AS,D:Session[AS]#DualOf](session:	AS,	dual:	D)	=	
				implicitly[Session[AS]#DualOf[D]].run(session,	dual)
Stop Dual
	 	
	implicit	object	StopDual	extends	Session[Stop]	{	
	 	 type	Dual	=	Stop	
	 	 def	run	(self:	Self,	dual:	Dual):	Unit	=	{}	
	 }
In Dual
	 	
		implicit	def	InDual[R[S<:State],RA<:State,RB<:State,C](implicit	cont:	Session[C])		
				=	new	Session[In[R,RA,RB,C]]	{	
					type	Dual	=	Out[R,RA,cont.Dual]	
					def	run(self:	Self,	dual:	Dual)	=	cont.run(self.recv(dual.data)._1,	dual.cont)	
			}
Type of In Dual
	 	
		implicit	def	InDual[R[S<:State],RA<:State,RB<:State,C](implicit	cont:	Session[C])		
				=	new	Session[In[R,RA,RB,C]]	{	
					type	Dual	=	Out[R,RA,cont.Dual]	
					def	run(self:	Self,	dual:	Dual)	=	cont.run(self.recv(dual.data)._1,	dual.cont)	
			}
Out Dual
			
	implicit	def	OutDual[R[S<:State],RA<:State,RB<:State,C](implicit	cont:	Session[C])		
			=	new	Session[Out[R,RA,C]]	{	
				type	Dual	=	In[R,RA,RB,cont.Dual]	
				def	run(self:	Self,	dual:	Dual)	=	cont.run(self.cont,	dual.recv(self.data)._1)	
		}
Source Code
http://bit.ly/1VnWX2R
Run
scala>	:load	SessionTypes.scala	
Loading	SessionTypes.scala...	
defined	module	SessionTypes	
scala>	SessionTypes.doRun	
Client	results:	Parcel(First,Receiver,Address)	and	
Parcel(Second,Receiver,Address)	
Server	result:	Parcel(Changed	by	server	First,Receiver,Address)	
scala>
Close the post
		sealed	abstract	class	~>[-A,+B]	
		//implicit	case	object	GoToThePost			 	 	 	extends	~>[Packaged,Sending]	
		implicit	case	object	AcceptFromSender		 extends	~>[Sending,Moving]	
		implicit	case	object	BringToTheAddress		extends	~>[Moving,Received]	
		implicit	case	object	GiveToReceiver			 	extends	~>[Received,Delivered]	
		implicit	case	object	GetAngry			 	 	 	 	 	extends	~>[Moving,Destroyed]	
		implicit	case	object	DrinkAlcohol			 	 	extends	~>[Moving,Lost]	
		implicit	case	object	StopDrinking			 	 	extends	~>[Lost,Moving]
Run
scala>	:load	SessionTypes.scala	
Loading	SessionTypes.scala...	
<console>:75:	error:	state	transition	from	SessionTypes.Packaged	to	
SessionTypes.Sending	is	not	allowed	
											In	{	p:	Parcel[Packaged]	=>	
														^	
scala>
Avoid the post
			
def	server	=	
				In	{	p:	Parcel[Packaged]	=>	
						val	content	=	"Changed	by	server	"	+	p.content	
						val	result	=	Parcel[Moving](content,	p.receiver,	p.address)	
						val	stop	=	Stop("With	server	result:	"	+	result)	
						(stop,	result)	
				}
Run
scala>	:load	SessionTypes.scala	
Loading	SessionTypes.scala...	
<console>:75:	error:	state	transition	from	SessionTypes.Packaged	to	
SessionTypes.Moving	is	not	allowed	
											In	{	p:	Parcel[Packaged]	=>	
														^	
scala>
Wrong initial state
			
def	server	=	
				In	{	p:	Parcel[Sending]	=>	
						val	content	=	"Changed	by	server	"	+	p.content	
						val	result	=	Parcel[Moving](content,	p.receiver,	p.address)	
						val	stop	=	Stop("With	server	result:	"	+	result)	
						(stop,	result)	
				}
Run
scala>	:load	SessionTypes.scala	
Loading	SessionTypes.scala...	
<console>:110:	error:	could	not	find	implicit	value	for	evidence	
parameter	of	type	
SessionTypes.Session[SessionTypes.In[SessionTypes.Parcel,SessionTypes
.Sended,SessionTypes.Moving,SessionTypes.Stop]]{type	Dual	=	
SessionTypes.Out[SessionTypes.Parcel,SessionTypes.Packaged,SessionTyp
es.Stop]}	
									def	run	=	runSession(server,	client)	
																													^	
scala>
Misaligned step
			
def	server	=	
				In	{	p:	Parcel[Sending]	=>	
						val	content	=	"Changed	by	server	"	+	p.content	
						val	result	=	Parcel[Moving](content,	p.receiver,	p.address)	
						val	stop	=	Stop("With	server	result:	"	+	result)	
						(Out(result,	stop),	result)	
				}
Run
scala>	:load	SessionTypes.scala	
Loading	SessionTypes.scala...	
<console>:110:	error:	could	not	find	implicit	value	for	evidence	
parameter	of	type	
SessionTypes.Session[SessionTypes.In[SessionTypes.Parcel,SessionTypes
.Sended,SessionTypes.Moving,SessionTypes.Out[SessionTypes.Parcel,Sess
ionTypes.Moving,SessionTypes.Stop]]]{type	Dual	=	
SessionTypes.Out[SessionTypes.Parcel,SessionTypes.Packaged,SessionTyp
es.Stop]}	
									def	run	=	runSession(server,	client)	
																													^	
scala>
?
Session Types Primitives
Sending
Receiving
Sequence
Choice
Recursion
Oops….
Session Types Primitives
Sending
Receiving
Sequence
Choice
Recursion
Session
Types
REST
Contract first, session types never?
• No API Specification standard is about REST
• REST “allows” for client-side contract checking
• Session Types don’t fit RESTful communications
Questions ?
Thank you!

Weitere ähnliche Inhalte

Was ist angesagt?

WEBINAR: Positive Security for APIs: What it is and why you need it!
 WEBINAR: Positive Security for APIs: What it is and why you need it! WEBINAR: Positive Security for APIs: What it is and why you need it!
WEBINAR: Positive Security for APIs: What it is and why you need it!
42Crunch
 

Was ist angesagt? (20)

API Security and Management Best Practices
API Security and Management Best PracticesAPI Security and Management Best Practices
API Security and Management Best Practices
 
Checkmarx meetup API Security - API Security in depth - Inon Shkedy
Checkmarx meetup API Security - API Security in depth - Inon ShkedyCheckmarx meetup API Security - API Security in depth - Inon Shkedy
Checkmarx meetup API Security - API Security in depth - Inon Shkedy
 
Microservices with Swagger, Flask and Docker
Microservices with Swagger, Flask and DockerMicroservices with Swagger, Flask and Docker
Microservices with Swagger, Flask and Docker
 
Mobile Application Security Testing (Static Code Analysis) of Android App
Mobile Application Security Testing (Static Code Analysis) of Android AppMobile Application Security Testing (Static Code Analysis) of Android App
Mobile Application Security Testing (Static Code Analysis) of Android App
 
Protecting Your APIs Against Attack & Hijack
Protecting Your APIs Against Attack & Hijack Protecting Your APIs Against Attack & Hijack
Protecting Your APIs Against Attack & Hijack
 
Securty Testing For RESTful Applications
Securty Testing For RESTful ApplicationsSecurty Testing For RESTful Applications
Securty Testing For RESTful Applications
 
Guide on scaling web app
Guide on scaling web appGuide on scaling web app
Guide on scaling web app
 
Using & Abusing APIs: An Examination of the API Attack Surface
Using & Abusing APIs: An Examination of the API Attack SurfaceUsing & Abusing APIs: An Examination of the API Attack Surface
Using & Abusing APIs: An Examination of the API Attack Surface
 
WEBINAR: Positive Security for APIs: What it is and why you need it!
 WEBINAR: Positive Security for APIs: What it is and why you need it! WEBINAR: Positive Security for APIs: What it is and why you need it!
WEBINAR: Positive Security for APIs: What it is and why you need it!
 
API Test Automation
API Test Automation API Test Automation
API Test Automation
 
APISecurity_OWASP_MitigationGuide
APISecurity_OWASP_MitigationGuide APISecurity_OWASP_MitigationGuide
APISecurity_OWASP_MitigationGuide
 
Are You Properly Using JWTs?
Are You Properly Using JWTs?Are You Properly Using JWTs?
Are You Properly Using JWTs?
 
Best Practices You Must Apply to Secure Your APIs - Scott Morrison, SVP & Dis...
Best Practices You Must Apply to Secure Your APIs - Scott Morrison, SVP & Dis...Best Practices You Must Apply to Secure Your APIs - Scott Morrison, SVP & Dis...
Best Practices You Must Apply to Secure Your APIs - Scott Morrison, SVP & Dis...
 
API Security & Federation Patterns - Francois Lascelles, Chief Architect, Lay...
API Security & Federation Patterns - Francois Lascelles, Chief Architect, Lay...API Security & Federation Patterns - Francois Lascelles, Chief Architect, Lay...
API Security & Federation Patterns - Francois Lascelles, Chief Architect, Lay...
 
OWASP API Security Top 10 - API World
OWASP API Security Top 10 - API WorldOWASP API Security Top 10 - API World
OWASP API Security Top 10 - API World
 
Nullcon Goa 2016 - Automated Mobile Application Security Testing with Mobile ...
Nullcon Goa 2016 - Automated Mobile Application Security Testing with Mobile ...Nullcon Goa 2016 - Automated Mobile Application Security Testing with Mobile ...
Nullcon Goa 2016 - Automated Mobile Application Security Testing with Mobile ...
 
Security enforcement of Java Microservices with Apiman & Keycloak
Security enforcement of Java Microservices with Apiman & KeycloakSecurity enforcement of Java Microservices with Apiman & Keycloak
Security enforcement of Java Microservices with Apiman & Keycloak
 
Best Practices in Building an API Security Ecosystem
Best Practices in Building an API Security EcosystemBest Practices in Building an API Security Ecosystem
Best Practices in Building an API Security Ecosystem
 
apidays LIVE Hong Kong - Orchestrating APIs at Scale by Hieu Nguyen Nhu
apidays LIVE Hong Kong - Orchestrating APIs at Scale by Hieu Nguyen Nhuapidays LIVE Hong Kong - Orchestrating APIs at Scale by Hieu Nguyen Nhu
apidays LIVE Hong Kong - Orchestrating APIs at Scale by Hieu Nguyen Nhu
 
Realtime web experience with signalR
Realtime web experience with signalRRealtime web experience with signalR
Realtime web experience with signalR
 

Ähnlich wie Contract first, session types later?

Access control patterns
Access control patterns Access control patterns
Access control patterns
WSO2
 
Building Realtime Web Applications With ASP.NET SignalR
Building Realtime Web Applications With ASP.NET SignalRBuilding Realtime Web Applications With ASP.NET SignalR
Building Realtime Web Applications With ASP.NET SignalR
Shravan Kumar Kasagoni
 

Ähnlich wie Contract first, session types later? (20)

Apidays Paris 2023 - Securing Microservice-based APIs, Michal Trojanowski, Cu...
Apidays Paris 2023 - Securing Microservice-based APIs, Michal Trojanowski, Cu...Apidays Paris 2023 - Securing Microservice-based APIs, Michal Trojanowski, Cu...
Apidays Paris 2023 - Securing Microservice-based APIs, Michal Trojanowski, Cu...
 
Web application
Web applicationWeb application
Web application
 
WSO2Con USA 2014 - Identity Server Tutorial
WSO2Con USA 2014 - Identity Server TutorialWSO2Con USA 2014 - Identity Server Tutorial
WSO2Con USA 2014 - Identity Server Tutorial
 
[Spring Camp 2018] 11번가 Spring Cloud 기반 MSA로의 전환 : 지난 1년간의 이야기
[Spring Camp 2018] 11번가 Spring Cloud 기반 MSA로의 전환 : 지난 1년간의 이야기[Spring Camp 2018] 11번가 Spring Cloud 기반 MSA로의 전환 : 지난 1년간의 이야기
[Spring Camp 2018] 11번가 Spring Cloud 기반 MSA로의 전환 : 지난 1년간의 이야기
 
Real Time Web with SignalR
Real Time Web with SignalRReal Time Web with SignalR
Real Time Web with SignalR
 
Intro to signalR
Intro to signalRIntro to signalR
Intro to signalR
 
Xamarin Workshop Noob to Master – Week 5
Xamarin Workshop Noob to Master – Week 5Xamarin Workshop Noob to Master – Week 5
Xamarin Workshop Noob to Master – Week 5
 
re:Invent ARC307 - Serverless architectural patterns and best practices.pdf
re:Invent ARC307 - Serverless architectural patterns and best practices.pdfre:Invent ARC307 - Serverless architectural patterns and best practices.pdf
re:Invent ARC307 - Serverless architectural patterns and best practices.pdf
 
Dive in burpsuite
Dive in burpsuiteDive in burpsuite
Dive in burpsuite
 
Access control patterns
Access control patterns Access control patterns
Access control patterns
 
RoR 101: Session 3
RoR 101: Session 3RoR 101: Session 3
RoR 101: Session 3
 
APIs enabling IoT
APIs enabling IoT APIs enabling IoT
APIs enabling IoT
 
Building Realtime Web Applications With ASP.NET SignalR
Building Realtime Web Applications With ASP.NET SignalRBuilding Realtime Web Applications With ASP.NET SignalR
Building Realtime Web Applications With ASP.NET SignalR
 
OpenFabrics Interfaces introduction
OpenFabrics Interfaces introductionOpenFabrics Interfaces introduction
OpenFabrics Interfaces introduction
 
SignalR or gRPC: Choosing the Right Technology for Real-Time Communication in...
SignalR or gRPC: Choosing the Right Technology for Real-Time Communication in...SignalR or gRPC: Choosing the Right Technology for Real-Time Communication in...
SignalR or gRPC: Choosing the Right Technology for Real-Time Communication in...
 
Beginning Microservices with .NET & RabbitMQ
Beginning Microservices with .NET & RabbitMQBeginning Microservices with .NET & RabbitMQ
Beginning Microservices with .NET & RabbitMQ
 
DevDay: Developer Updates: Visual Studio Code, Java 11 and OpenAPI (oh my), L...
DevDay: Developer Updates: Visual Studio Code, Java 11 and OpenAPI (oh my), L...DevDay: Developer Updates: Visual Studio Code, Java 11 and OpenAPI (oh my), L...
DevDay: Developer Updates: Visual Studio Code, Java 11 and OpenAPI (oh my), L...
 
Distributed objects
Distributed objectsDistributed objects
Distributed objects
 
Real-time ASP.NET with SignalR
Real-time ASP.NET with SignalRReal-time ASP.NET with SignalR
Real-time ASP.NET with SignalR
 
Application Security Workshop
Application Security Workshop Application Security Workshop
Application Security Workshop
 

Kürzlich hochgeladen

The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
shinachiaurasa2
 
+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
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
masabamasaba
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
masabamasaba
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
masabamasaba
 
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...
Medical / Health Care (+971588192166) Mifepristone and Misoprostol tablets 200mg
 

Kürzlich hochgeladen (20)

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...
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
 
%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
 
+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...
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
%+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...
 
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...
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
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...
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the past
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go Platformless
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
 
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
 

Contract first, session types later?