Skip to main content
TIPS AND TRICKS FOR YOUR
SERVICE ORIENTED
ARCHITECTURE
CakeFest, San Francisco, Sep 2013
WARNING
NO
CAKEPHP
AHEAD
This talk is for those...
Stuck with the legacy
dealing with CRONs
in the need of a solid foundation
rely on web services
need a pluggable software architecture
SOA
Agenda
1. Service Oriented WHAT?!?!
2. Tips, Tricks and lessons learned (the hard way)
3. Conclusion
1
SO(A) WHAT?
A software design based on discrete software
components, "services", that collectively
provide the functionalities of the larger
software application
You typically start with the
infamous web application
which does everything on its own
Then you realize that to provide
a chat system to your users
PHP might not be the best...
And soon you also decide,
to improve performances,
that your frontend should have its own
in-memory persistence, to be faster
and you put it into another service
Then, as always...
SCALE.
And eventually, your lead architect
will come up and tell you
that your Java-based chat
sucks and should be
replaced with...
NODEJS
In human-understandable words, SOA is a software design which
embraces splitting a monolithic, totalitarian software
architecture into smaller pieces, thus making them independent,
loosely coupled and more maintainable
Ok, but in the real world?
A few points...
DATA
each service might have its own data-layer, but nothing
prevents you from sharing data across the services
reads: abstract the data
WEBSERVICES
Services can request data to other services,
usually through WSs
POX
SOAP
HTTP
REST
Note to self:
check the difference
between HTTP and
REST APIs
Note to self:
check the difference
between HTTP and
REST APIs
(HATEOAS)
Note to self:
check the difference
between HTTP and
REST APIs
(HATEOAS)
EVENTS
services notify the architecture that an event has happened
asynchronous messaging queues
2
TIPS AND
TRICKS
LEARNT THE
HARD WAY
2.1 AVOID SOA
DIFFICULT TO TEST
COMPLEX
SOA would be
overkill for most
of the common
scenarios
But if you're handling
a product or a
monolithic software
stack, the added
complexity pays off
on the long run
2.2 FREE
THE DATA
CONSIDER ELIMINATING FK CONSTRAINTS
A service might need to handle data with
another DBMS, so FKs are virtually impossible
ABSTRACT THE DATA
You might think in "rows" but the architecture
thinks in "resources"
No more FKs and
the ability of
JOINing to retrieve
some related data
But you choose
what perfectly fits
each service:
your transactions
over a RDBMS and
your community
over a graph DB
2.3 Standardize
Build a vast suite of E2E tests
and give your developer a way to easily test
EVERY DEVELOPER NEEDS
THE ENTIRE ARCHITECTURE ON LOCAL
The architecture needs
to be installed in
~1 hour
Setting up VMs
is an hassle and
they are so slow!
go #vagrant
2.4 IDENTIFY
WISELY
AUTHENTICATION IS KING
Centralized authentication = identity service
NEVER HANDLE CREDENTIALS IN CLEAR
NEVER.
man in the middle
NEVER.
man in the middle
SSL
NEVER.
man in the middle
SSL
tokenize
OAuth
OpenID
JWS
JSON WEB SIGNATURE
JSON WEB TOKEN
JSON WEB SIGNATURE
JAVASCRIPT OBJECT
SIGNING & ENCRYPTION
JOSE
http://www.thread-safe.com/2012/03/json-object-signing-and-encryption-jose.html
1. The user enters the
credentials once in your
frontend
JS APP
AUTH
SERVICE
2. The JS app will forward them
to your Auth webservice
3. The Auth webservice will
then generate the encrypted
JWS and set a cookie with
its value
JS APP
4. The JS app can now just
execute calls using
that cookie
1. The user enters the credentials
once in your frontend
JS APP
AUTH
SERVICE
2. The JS app will forward them
to your Auth webservice
JS APP
AUTH
SERVICE
3. The Auth webservice will then generate the
encrypted JWS and set a cookie with its value
JS APP
AUTH
SERVICE
4. The JS app can now just execute
calls using that cookie
1. The user enters the
credentials once in your
frontend
JS APP
AUTH
SERVICE
2. The JS app will forward them
to your Auth webservice
3. The Auth webservice will
then generate the encrypted
JWS and set a cookie with
its value
JS APP
4. The JS app can now just
execute calls using
that cookie
setcookie($name, $jws,$ttl, $path, $domain, true);
setcookie($name, $jws,$ttl, $path, $domain, true);
HTTPS
JWS in PHP?
namshi/jose
use NamshiJOSEJWS;
$jws = new JWS('RS256');
$jws->setPayload(array(
'uid' => $user->getid(),
));
$privateKey = openssl_get_privatekey("file://path/to/private.
key");
$jws->sign($privateKey);
setcookie('identity', $jws->getTokenString());
use NamshiJOSEJWS;
$jws = JWS::load($_COOKIE['identity']);
$public_key = openssl_pkey_get_public("/path/to/public.key");
if ($jws->verify($public_key)) {
echo "EUREKA!;
}
use NamshiJOSEJWS;
$jws = new JWS('RS256');
$jws->setPayload(array(
'uid' => $user->getid(),
));
$privateKey = openssl_get_privatekey("file://path/to/private.
key");
$jws->sign($privateKey);
setcookie('identity', $jws->getTokenString());
use NamshiJOSEJWS;
$jws = JWS::load($_COOKIE['identity']);
$public_key = openssl_pkey_get_public("/path/to/public.key");
if ($jws->verify($public_key)) {
echo "EUREKA!;
}
use NamshiJOSEJWS;
$jws = new JWS('RS256');
$jws->setPayload(array(
'uid' => $user->getid(),
));
$privateKey = openssl_get_privatekey("file://path/to/private.
key");
$jws->sign($privateKey);
setcookie('identity', $jws->getTokenString());
use NamshiJOSEJWS;
$jws = JWS::load($_COOKIE['identity']);
$public_key = openssl_pkey_get_public("/path/to/public.key");
if ($jws->verify($public_key)) {
echo "EUREKA!;
}
use NamshiJOSEJWS;
$jws = new JWS('RS256');
$jws->setPayload(array(
'uid' => $user->getid(),
));
$privateKey = openssl_get_privatekey("file://path/to/private.
key");
$jws->sign($privateKey);
setcookie('identity', $jws->getTokenString(), ...);
use NamshiJOSEJWS;
$jws = JWS::load($_COOKIE['identity']);
$public_key = openssl_pkey_get_public("/path/to/public.key");
if ($jws->verify($public_key)) {
echo "EUREKA!;
}
use NamshiJOSEJWS;
$jws = new JWS('RS256');
$jws->setPayload(array(
'uid' => $user->getid(),
));
$privateKey = openssl_get_privatekey("file://path/to/private.
key");
$jws->sign($privateKey);
setcookie('identity', $jws->getTokenString());
use NamshiJOSEJWS;
$jws = JWS::load($_COOKIE['identity']);
$public_key = openssl_pkey_get_public("/path/to/public.key");
if ($jws->verify($public_key)) {
echo "EUREKA!;
}
use NamshiJOSEJWS;
$jws = new JWS('RS256');
$jws->setPayload(array(
'uid' => $user->getid(),
));
$privateKey = openssl_get_privatekey("file://path/to/private.
key");
$jws->sign($privateKey);
setcookie('identity', $jws->getTokenString());
use NamshiJOSEJWS;
$jws = JWS::load($_COOKIE['identity']);
$public_key = openssl_pkey_get_public("/path/to/public.key");
if ($jws->verify($public_key)) {
echo "EUREKA!;
}
I can't simply
use the HTTP
basic authentication,
it was so
convenient!