SlideShare a Scribd company logo
1 of 55
Download to read offline
@adam_englander
BDD API Development with
Symfony and Behat
Adam Englander
LaunchKey Architect, iovation
@adam_englander
Architectural Landscape
@adam_englander
APIs are taking over!
@adam_englander
Mobile Applications
Android
iOS
Windows
Mobile
API
@adam_englander
Single Page Applications
API
@adam_englander
Application Extensibility
API
Your
Shipping
Application Integrations
@adam_englander
Internet of Things
API
@adam_englander
Microservices
Messaging
Distribution
Auth
Orders
Customer
@adam_englander
APIs in Symfony
@adam_englander
Symfony is Extensible
@adam_englander
Your Application Bundle
@adam_englander
Your Application Bundle
Routing
@adam_englander
Your Application Bundle
Routing Serializer
@adam_englander
Your Application Bundle
Routing Firewall Serializer
@adam_englander
Your Application Bundle
Routing Firewall Serializer
Cache
@adam_englander
Your Application Bundle
Routing Firewall Serializer
Event Dispatcher Cache
@adam_englander
Your Application Bundle
Routing Firewall Serializer
Event Dispatcher
Dependency
Cache
@adam_englander
Your Application Bundle
Routing Firewall Serializer
Event Dispatcher
Config
Dependency
Cache
@adam_englander
Your Application Bundle
Routing Firewall Serializer
Event Dispatcher
Config
TranslationDependency
Cache
@adam_englander
Your Application Bundle
Routing Firewall Serializer
Event Dispatcher
Config App Kernels
TranslationDependency
Cache
@adam_englander
Your Application Bundle
Routing Firewall Serializer
Event Dispatcher
Config App Kernels
TranslationDependency
Cache
Full Integration Testing Required
@adam_englander
PHPUnit vs. Behat
@adam_englander
Acceptance
Documentation
Live Tests
Kernel TestsBehat
@adam_englander
Acceptance
Documentation
Live Tests
Kernel TestsPHPUnit
@adam_englander
Behavior Driven Development
is for websites!
@adam_englander
Behavior is Behavior
Web Mobile Device to Device
@adam_englander
Actor 1 Acts -> Actor 2 Responds
Show the
homepage
Here is the
homepage
Adam is home
I turned on
the lights
@adam_englander
Instead of dealing with this:
@adam_englander
Well, actually, this:
<!DOCTYPE html>
<head>
<title>Symfony</title>
</head>
<body>
<div class="position-relative js-header-wrapper">
<a href="#start" tabindex="1" class=“bg-black">
Skip to content
</a>
<div id="loader-bar" class=“pjax-loader-bar”>
<div class=“progress"></div>
</div>
. . .
@adam_englander
You are dealing with this:
HTTP/1.1 200 OK
Date: Thu, 19 Oct 2017 06:28:02 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 1009
Server: GitHub.com
Status: 200 OK
Vary: Accept-Encoding
X-GitHub-Request-Id: CD6C:D7DE:E24F3B2:123F37BB:59E845F1
{
"login": "symfony",
"id": 143937,
"url": "https://api.github.com/orgs/symfony",
. . .
@adam_englander
Feature: All pages require login
As a user
In order to view the home page
I must login to the website
Scenario: Not logged in redirects to login page
When I go to the home page
Then I am redirected to the login page
Scenario: Logged sees page
Given I am logged in
When I go to the home page
Then I see hello Adam
Web
@adam_englander
Feature: All endpoints require OAuth token
As an API consumer
In order to access an endpoint
I must be authenticated
Scenario: Not logged in shows 401
When I access the status endpoint
Then the HTTPS Status is 401 Unauthorized
And the WWW-Authenticate header is Bearer
realm=“API Realm”
Scenario: Authorized returns endpoint response
Given a valid OAuth Token
When I access the status endpoint
Then the HTTP Status is 200 OK
Device to
Device
@adam_englander
That’s nice and all. How do I do
Kernel and Live tests?
@adam_englander
Multi-Profile — Multi-Client
@adam_englander
Default Profile: Symfony Extension
default:
extensions:
BehatSymfony2Extension: ~
suites:
default:
contexts: [SymfonyKernelFeatureContext]
@adam_englander
Server Profile: Guzzle Client
server:
extensions: []
suites:
default:
contexts:
- GuzzleFeatureContext:
- base_uri: http://localhost:8000
@adam_englander
Context Hierarchy
Abstract
Context
Symfony
Kernel
Context
Guzzle
Client
Context
@adam_englander
Abstract Context
protected abstract function sendRequestImpl(
RequestInterface $request): ResponseInterface;
/**
* @Then /^the response status code is (d+)$/
*/
public function theResponseStatusCodeIs($statusCode)
{
MatcherAssert::assertThat(
$this->response->getStatusCode(),
Matchers::equalTo($statusCode)
);
}
@adam_englander
Guzzle Client Context
"require-dev": {
"guzzlehttp/guzzle": “^6.3”,
. . .
@adam_englander
Guzzle Client Context
public function __construct($config)
{
$this->client = new GuzzleHttpClient($config);
}
@adam_englander
Guzzle Client Context
protected function sendRequestImpl($request) {
try {
$response = $this->client->send($request);
} catch (ClientException $clientException) {
$response = $clientException->getResponse();
}
return $response;
}
@adam_englander
Symfony Kernel Context
"require-dev": {
"behat/symfony2-extension": “^2.1.1",
"symfony/psr-http-message-bridge": "^1.0",
"zendframework/zend-diactoros": "^1.4"
. . .
}
@adam_englander
Symfony Kernel Context
class SymfonyKernelFeatureContext
extends AbstractFeatureContext
implements KernelAwareContext
public function __construct() {
$this->psr7Factory = new DiactorosFactory();
}
public function setKernel(KernelInterface $kernel) {
$this->client = $kernel
->getContainer()->get(‘test.client');
}
@adam_englander
Symfony Kernel Context
protected function sendRequestImpl($request) {
$this->client->request(
$request->getMethod(),
$request->getUri()->getPath());
$clientResponse = $this->client->getResponse();
$response = $this->psr7Factory
->createResponse($clientResponse);
return $response;
}
@adam_englander
That Was Easy!
@adam_englander
Lessons From the Trenches
@adam_englander
LaunchKey MFA API
41 Unique paths
130 handler methods
~10K lines of code
120 libraries
@adam_englander
LaunchKey MFA API Tests
55 Features
328 Scenarios
~3K lines of step code
@adam_englander
Split feature files by functional
features not by path.
@adam_englander
Break functionality into multiple
contexts like you would bundles.
@adam_englander
If you have complex step code,
unit test that code!
@adam_englander
Expose endpoints for setup and
teardown.
@adam_englander
Test a feature only once. Every step
that is not testing the feature is a
Given.
@adam_englander
Every Given needs to be tested
in another Feature.
@adam_englander
https://joind.in/talk/ead28

More Related Content

What's hot

I can haz HTTP - Consuming and producing HTTP APIs in the Ruby ecosystem
I can haz HTTP - Consuming and producing HTTP APIs in the Ruby ecosystemI can haz HTTP - Consuming and producing HTTP APIs in the Ruby ecosystem
I can haz HTTP - Consuming and producing HTTP APIs in the Ruby ecosystem
Sidu Ponnappa
 
Introduction to Spring Boot!
Introduction to Spring Boot!Introduction to Spring Boot!
Introduction to Spring Boot!
Jakub Kubrynski
 

What's hot (20)

All the Laravel things: up and running to making $$
All the Laravel things: up and running to making $$All the Laravel things: up and running to making $$
All the Laravel things: up and running to making $$
 
eMusic: WordPress in the Enterprise
eMusic: WordPress in the EnterpriseeMusic: WordPress in the Enterprise
eMusic: WordPress in the Enterprise
 
Grand Rapids PHP Meetup: Behavioral Driven Development with Behat
Grand Rapids PHP Meetup: Behavioral Driven Development with BehatGrand Rapids PHP Meetup: Behavioral Driven Development with Behat
Grand Rapids PHP Meetup: Behavioral Driven Development with Behat
 
ElasticBeanstalk で新規事業を爆速ローンチする
ElasticBeanstalk で新規事業を爆速ローンチするElasticBeanstalk で新規事業を爆速ローンチする
ElasticBeanstalk で新規事業を爆速ローンチする
 
Amazon inspector で自動セキュリティ診断
Amazon inspector で自動セキュリティ診断Amazon inspector で自動セキュリティ診断
Amazon inspector で自動セキュリティ診断
 
I can haz HTTP - Consuming and producing HTTP APIs in the Ruby ecosystem
I can haz HTTP - Consuming and producing HTTP APIs in the Ruby ecosystemI can haz HTTP - Consuming and producing HTTP APIs in the Ruby ecosystem
I can haz HTTP - Consuming and producing HTTP APIs in the Ruby ecosystem
 
Try to use chromeless on AWS Lambda
Try to use chromeless on AWS LambdaTry to use chromeless on AWS Lambda
Try to use chromeless on AWS Lambda
 
The tale of 100 cve's
The tale of 100 cve'sThe tale of 100 cve's
The tale of 100 cve's
 
Composer Power User Tips
Composer Power User TipsComposer Power User Tips
Composer Power User Tips
 
Introduction to Spring Boot!
Introduction to Spring Boot!Introduction to Spring Boot!
Introduction to Spring Boot!
 
What's New in Laravel 5 (Laravel Meetup - 23th Apr 15, Yogyakarta, ID)
What's New in Laravel 5 (Laravel Meetup - 23th Apr 15, Yogyakarta, ID)What's New in Laravel 5 (Laravel Meetup - 23th Apr 15, Yogyakarta, ID)
What's New in Laravel 5 (Laravel Meetup - 23th Apr 15, Yogyakarta, ID)
 
php[world] 2015 Training - Laravel from the Ground Up
php[world] 2015 Training - Laravel from the Ground Upphp[world] 2015 Training - Laravel from the Ground Up
php[world] 2015 Training - Laravel from the Ground Up
 
Digpen 7: Why choose Laravel?
Digpen 7: Why choose Laravel?Digpen 7: Why choose Laravel?
Digpen 7: Why choose Laravel?
 
CakePHP 2.0 - PHP Matsuri 2011
CakePHP 2.0 - PHP Matsuri 2011CakePHP 2.0 - PHP Matsuri 2011
CakePHP 2.0 - PHP Matsuri 2011
 
Knowing Laravel 5 : The most popular PHP framework
Knowing Laravel 5 : The most popular PHP frameworkKnowing Laravel 5 : The most popular PHP framework
Knowing Laravel 5 : The most popular PHP framework
 
One does not simply "Upgrade to Rails 3"
One does not simply "Upgrade to Rails 3"One does not simply "Upgrade to Rails 3"
One does not simply "Upgrade to Rails 3"
 
You are not_hiding_from_me_.net
You are not_hiding_from_me_.netYou are not_hiding_from_me_.net
You are not_hiding_from_me_.net
 
Ansible, Idempotency, and Jenkins
Ansible, Idempotency, and JenkinsAnsible, Idempotency, and Jenkins
Ansible, Idempotency, and Jenkins
 
Introducing Ext JS 4
Introducing Ext JS 4Introducing Ext JS 4
Introducing Ext JS 4
 
"Design First" APIs with Swagger
"Design First" APIs with Swagger"Design First" APIs with Swagger
"Design First" APIs with Swagger
 

Similar to Symfony Live San Franciso 2017 - BDD API Development with Symfony and Behat

Hacking Client Side Insecurities
Hacking Client Side InsecuritiesHacking Client Side Insecurities
Hacking Client Side Insecurities
amiable_indian
 

Similar to Symfony Live San Franciso 2017 - BDD API Development with Symfony and Behat (20)

Serverless Design Patterns
Serverless Design PatternsServerless Design Patterns
Serverless Design Patterns
 
Serverless Beyond Functions - CTO Club Made in JLM
Serverless Beyond Functions - CTO Club Made in JLMServerless Beyond Functions - CTO Club Made in JLM
Serverless Beyond Functions - CTO Club Made in JLM
 
Serverless Design Patterns
Serverless Design PatternsServerless Design Patterns
Serverless Design Patterns
 
Serveless design patterns (VoxxedDays Luxembourg)
Serveless design patterns (VoxxedDays Luxembourg)Serveless design patterns (VoxxedDays Luxembourg)
Serveless design patterns (VoxxedDays Luxembourg)
 
Serveless design patterns
Serveless design patternsServeless design patterns
Serveless design patterns
 
Hacking Client Side Insecurities
Hacking Client Side InsecuritiesHacking Client Side Insecurities
Hacking Client Side Insecurities
 
Serveless Design Patterns (Serverless Computing London)
Serveless Design Patterns (Serverless Computing London)Serveless Design Patterns (Serverless Computing London)
Serveless Design Patterns (Serverless Computing London)
 
Integrating Ansible Tower with security orchestration and cloud management
Integrating Ansible Tower with security orchestration and cloud managementIntegrating Ansible Tower with security orchestration and cloud management
Integrating Ansible Tower with security orchestration and cloud management
 
(MBL205) New! Everything You Want to Know About AWS IoT
(MBL205) New! Everything You Want to Know About AWS IoT(MBL205) New! Everything You Want to Know About AWS IoT
(MBL205) New! Everything You Want to Know About AWS IoT
 
Serverless Design Patterns (London Dev Community)
Serverless Design Patterns (London Dev Community)Serverless Design Patterns (London Dev Community)
Serverless Design Patterns (London Dev Community)
 
Ovations AWS pop-up loft 2019 Technical presentation
Ovations AWS pop-up loft 2019 Technical presentationOvations AWS pop-up loft 2019 Technical presentation
Ovations AWS pop-up loft 2019 Technical presentation
 
Building Voice Controls and Integrating with Automation Actions on an IoT Net...
Building Voice Controls and Integrating with Automation Actions on an IoT Net...Building Voice Controls and Integrating with Automation Actions on an IoT Net...
Building Voice Controls and Integrating with Automation Actions on an IoT Net...
 
Building Mobile Friendly APIs in Rails
Building Mobile Friendly APIs in RailsBuilding Mobile Friendly APIs in Rails
Building Mobile Friendly APIs in Rails
 
Event-Driven Serverless Apps - Pop-up Loft Tel Aviv
Event-Driven Serverless Apps - Pop-up Loft Tel AvivEvent-Driven Serverless Apps - Pop-up Loft Tel Aviv
Event-Driven Serverless Apps - Pop-up Loft Tel Aviv
 
Techdays Helsinki - Creating the distributed apps of the future using dapr - ...
Techdays Helsinki - Creating the distributed apps of the future using dapr - ...Techdays Helsinki - Creating the distributed apps of the future using dapr - ...
Techdays Helsinki - Creating the distributed apps of the future using dapr - ...
 
Building Secure Mobile APIs
Building Secure Mobile APIsBuilding Secure Mobile APIs
Building Secure Mobile APIs
 
Building Scalable Services with Amazon API Gateway - Technical 201
Building Scalable Services with Amazon API Gateway - Technical 201Building Scalable Services with Amazon API Gateway - Technical 201
Building Scalable Services with Amazon API Gateway - Technical 201
 
Trusted by Default: The Forge Security & Privacy Model
Trusted by Default: The Forge Security & Privacy ModelTrusted by Default: The Forge Security & Privacy Model
Trusted by Default: The Forge Security & Privacy Model
 
Beware the potholes
Beware the potholesBeware the potholes
Beware the potholes
 
Deep Dive - Hybrid Architectures
Deep Dive - Hybrid ArchitecturesDeep Dive - Hybrid Architectures
Deep Dive - Hybrid Architectures
 

More from Adam Englander

More from Adam Englander (20)

Making PHP Smarter - Dutch PHP 2023.pptx
Making PHP Smarter - Dutch PHP 2023.pptxMaking PHP Smarter - Dutch PHP 2023.pptx
Making PHP Smarter - Dutch PHP 2023.pptx
 
Practical API Security - PyCon 2019
Practical API Security - PyCon 2019Practical API Security - PyCon 2019
Practical API Security - PyCon 2019
 
Threat Modeling for Dummies
Threat Modeling for DummiesThreat Modeling for Dummies
Threat Modeling for Dummies
 
ZendCon 2018 - Practical API Security
ZendCon 2018 - Practical API SecurityZendCon 2018 - Practical API Security
ZendCon 2018 - Practical API Security
 
ZendCon 2018 - Cryptography in Depth
ZendCon 2018 - Cryptography in DepthZendCon 2018 - Cryptography in Depth
ZendCon 2018 - Cryptography in Depth
 
Threat Modeling for Dummies - Cascadia PHP 2018
Threat Modeling for Dummies - Cascadia PHP 2018Threat Modeling for Dummies - Cascadia PHP 2018
Threat Modeling for Dummies - Cascadia PHP 2018
 
Dutch PHP 2018 - Cryptography for Beginners
Dutch PHP 2018 - Cryptography for BeginnersDutch PHP 2018 - Cryptography for Beginners
Dutch PHP 2018 - Cryptography for Beginners
 
php[tek] 2108 - Cryptography Advances in PHP 7.2
php[tek] 2108 - Cryptography Advances in PHP 7.2php[tek] 2108 - Cryptography Advances in PHP 7.2
php[tek] 2108 - Cryptography Advances in PHP 7.2
 
php[tek] 2018 - Biometrics, fantastic failure point of the future
php[tek] 2018 - Biometrics, fantastic failure point of the futurephp[tek] 2018 - Biometrics, fantastic failure point of the future
php[tek] 2018 - Biometrics, fantastic failure point of the future
 
Biometrics: Sexy, Secure and... Stupid - RSAC 2018
Biometrics: Sexy, Secure and... Stupid - RSAC 2018Biometrics: Sexy, Secure and... Stupid - RSAC 2018
Biometrics: Sexy, Secure and... Stupid - RSAC 2018
 
Practical API Security - PyCon 2018
Practical API Security - PyCon 2018Practical API Security - PyCon 2018
Practical API Security - PyCon 2018
 
Practical API Security - Midwest PHP 2018
Practical API Security - Midwest PHP 2018Practical API Security - Midwest PHP 2018
Practical API Security - Midwest PHP 2018
 
Cryptography for Beginners - Midwest PHP 2018
Cryptography for Beginners - Midwest PHP 2018Cryptography for Beginners - Midwest PHP 2018
Cryptography for Beginners - Midwest PHP 2018
 
Cryptography for Beginners - Sunshine PHP 2018
Cryptography for Beginners - Sunshine PHP 2018Cryptography for Beginners - Sunshine PHP 2018
Cryptography for Beginners - Sunshine PHP 2018
 
ConFoo Vancouver 2017 - Biometrics: Fantastic Failure Point of the Future
ConFoo Vancouver 2017 - Biometrics: Fantastic Failure Point of the FutureConFoo Vancouver 2017 - Biometrics: Fantastic Failure Point of the Future
ConFoo Vancouver 2017 - Biometrics: Fantastic Failure Point of the Future
 
Con Foo 2017 - Don't Loose Sleep - Secure Your REST
Con Foo 2017 - Don't Loose Sleep - Secure Your RESTCon Foo 2017 - Don't Loose Sleep - Secure Your REST
Con Foo 2017 - Don't Loose Sleep - Secure Your REST
 
ZendCon 2017 - Cryptography for Beginners
ZendCon 2017 - Cryptography for BeginnersZendCon 2017 - Cryptography for Beginners
ZendCon 2017 - Cryptography for Beginners
 
ZendCon 2017: The Red Team is Coming
ZendCon 2017: The Red Team is ComingZendCon 2017: The Red Team is Coming
ZendCon 2017: The Red Team is Coming
 
ZendCon 2017 - Build a Bot Workshop - Async Primer
ZendCon 2017 - Build a Bot Workshop - Async PrimerZendCon 2017 - Build a Bot Workshop - Async Primer
ZendCon 2017 - Build a Bot Workshop - Async Primer
 
Coder Cruise 2017 - The Red Team Is Coming
Coder Cruise 2017 - The Red Team Is ComingCoder Cruise 2017 - The Red Team Is Coming
Coder Cruise 2017 - The Red Team Is Coming
 

Recently uploaded

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 

Recently uploaded (20)

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu SubbuApidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
 

Symfony Live San Franciso 2017 - BDD API Development with Symfony and Behat