Optimizing Business Potential: A Guide to Outsourcing Engineering Services in...
A2 from soap to rest
1. Software Architecture & Design
Architecture
From n-Tier to SOA
From SOAP to REST
Technical Debt
Design
From SQL to ORM, NoSQL and ODM
From RAD to MVC
SOLID principles
Domain Driven Design (DDD)
Applying patterns on Delphi code using mORMot
Software Architecture & Design
3. From SOAP to REST
SOAP
REST
JSON
Security
practice
From SOAP to REST
4. Simple Object Access Protocol
SOAP
XML
WSDL
Defines
Processing model
Extensibility model
Underlying protocol binding
Message construct
From SOAP to REST
5. Simple Object Access Protocol
Standard
Feature complete
Time proof
From SOAP to REST
6. Simple? Object Access Protocol
Standard
Feature complete
Time proof
Several implementations (1.0/1.1/WCF/J2EE)
Verbose and heavy (slow)
Complex
From SOAP to REST
8. REpresentational State Transfer
Share the 5 basic fundamentals of the web:
Everything is a resource
Every resource is identified
by a unique identifier
Use simple and uniform interfaces
Communication is done by representation
Every request is stateless
From SOAP to REST
9. REpresentational State Transfer
Share the 5 basic fundamentals of the web…
And share the same author as HTTP
(Roy Fielding)
From SOAP to REST
10. REpresentational State Transfer
Share the 5 basic fundamentals of the web
and the same author
But HTTP is not REST
REST may be transmitted without HTTP
e.g. mORMot supports direct in-process access,
named pipes, Windows messages or WebSockets
REST does not define nor expect anything like
headers, sessions, cookies, https
From SOAP to REST
11. REST is Resource-based
On Internet, data can be:
web page, image, video, file, etc.
It can also be dynamic output like
“get customers who are newly subscribed”
With REST, we start thinking
in terms of resources
rather than physical files or API
From SOAP to REST
12. REST Unique Identifier
You access the resource via its URI
http://www.mysite.com/pictures/logo.png
Image Resource
http://www.mysite.com/index.html
Static Resource
http://www.mysite.com/Customer/1001
Dynamic Resource returning XML or JSON content
http://www.mysite.com/Customer/1001/Picture
Dynamic Resource returning an image
From SOAP to REST
13. Unique Identifier
Older web techniques, (aspx or ColdFusion),
requested a resource by specifying parameters, e.g.
http://www.mysite.com/Default.aspx?a=1;a=2&b=1&a=3
Several URIs may return the same data
Evolving parameters
In REST, we add constraints to the URI
In fact, every URI should uniquely
represent one item of the data collection
From SOAP to REST
14. REST Unique Identifier
Some URI samples:
Get Customer details with name “dupont”
GET http://www.mysite.com/Customer/dupont
Get Customer details with name “smith”
GET http://www.mysite.com/Customer/smith
Get orders placed by customer “dupont”
GET http://www.mysite.com/Customer/dupont/orders
From SOAP to REST
15. REST Interfaces
Access those identified resources
via basic CRUD activity
identified by a set of HTTP verbs
GET Read
PUT Update
POST Create
DELETE Delete
From SOAP to REST
16. REST Interfaces
Access those identified resources
via basic CRUD activity
identified by a set of HTTP verbs
GET Read
PUT Update
POST Create
DELETE Delete
(even if the official RFC may not match this)
From SOAP to REST
17. REST Interfaces
Access those identified resources
like basic SQL statements
identified by a set of HTTP verbs
GET SELECT
PUT UPDATE
POST INSERT
DELETE DELETE
(do you see the RESTful ORM coming?)
From SOAP to REST
18. REST Interfaces
Combination of
HTTP method/verb
and resource URI
replaces a list of English-based methods, like
GetCustomer / InsertCustomer /
UpdateOrder / RemoveOrder
From SOAP to REST
20. REST is Stateless
Every request should be independent
so that we can scale up (load balancing)
so that modeling stays simple
as HTTP/1.1
i.e. as an independent transaction
that is unrelated to any previous request
Server-side is the only reference
Need conflict resolution (optimistic/pessimistic)
From SOAP to REST
21. REST transfert by Representation
What you are sending over the wire
is in fact a Representation
of the actual resource data
As XML
As JSON
From SOAP to REST
<Customer>
<ID>1234</ID>
<Name>Dupond</Name>
<Address>Tree street</Address>
</Customer>
{"Customer":
{"ID":1234, "Name":"Dupond", "Address":"Tree street"}}
22. REST transfert by Representation
What you are sending over the wire
is not a serialized object
but some values
Which may be implemented with an object
As XML
As JSON
From SOAP to REST
<Customer>
<ID>1234</ID>
<Name>Dupond</Name>
<Address>Tree street</Address>
</Customer>
{"Customer":
{"ID":1234, "Name":"Dupond", "Address":"Tree street"}}
23. JSON
JavaScript Object Notation (JSON)
Standard
Open
Simple and lightweight
text-based, human-readable format
for representing simple data structures
and associative arrays (called objects)
Designed for data Representation
From SOAP to REST
24. JSON types
Number 123.45
String "text"
Boolean true/false
Array [ ]
Object { }
Null null
+ non significant white spaces
From SOAP to REST
25. JSON types
Number 123.45
String "text"
Boolean true/false
Array [ ]
Object { }
Null null
+ non significant white spaces
Date/Time? Iso8601 Blob? Base64
From SOAP to REST
27. <Troll>XML</Troll>
{"Troll":"JSON"}
JSON
Truly human-readable
Native AJAX / JavaScript format
Compact (UTF-8 friendly)
Simple to implement and use
XML
Any complex (even custom) types
SOAP standard
Binary (CDATA)
Validation (XSDL)
From SOAP to REST
28. JSON/XML alternatives
Text
INI
TOML
YAML
Binary
BSON
MessagePack
Protocol Buffers
WCF
From SOAP to REST
29. RESTful Security
Security in Client-Server
is usually implemented by:
Process safety
Authentication
Authorization
From SOAP to REST
30. RESTful Security
Security in Client-Server
is usually implemented by:
Process safety
Does quality matters?
Authentication
Are you who you claim to be?
Authorization
What are you allowed to do?
From SOAP to REST
31. RESTful Security
Process safety
Code quality
Risk management
Testing
Feedback, peer review
Transmission encryption
Do not reinvent the wheel
From SOAP to REST
32. RESTful Security
Authentication
Authentication (from Greek: "real" or "genuine", from
"author") is the act of confirming the truth of an
attribute of a datum or entity. This might involve
confirming the identity of a person or software
program, tracing the origins of an artifact, or ensuring
that a product is what its packaging and labeling
claims to be. Authentication often involves verifying
the validity of at least one form of identification.
(Wikipedia)
From SOAP to REST
33. RESTful Security
RESTful Authentication
HTTP basic auth over HTTPS
Not user-friendly (weird popup)
Password is transmitted
Cookies and session management (OAuth)
HTTP-based: not RESTful
Man-In-the-Middle (MIM) and replay issues
Query Authentication with additional signature
Each resource request is authenticated
Signatures can be strong
Can be stateless
From SOAP to REST
34. RESTful Security
Query Authentication (one way to do it)
For instance, a generic URI sample:
GET /object?apiKey=Qwerty2010
should be transmitted as such:
GET /object?timestamp=1261496500&apiKey=Qwerty2010
&signature=abcdef0123456789
The string being signed is
"/object?apikey=Qwerty2010×tamp=1261496500"
and the signature is the SHA-256 hash of that string
using the private component of the API key.
From SOAP to REST
35. RESTful Security
Authentication patterns
Password stored as hash
N-way challenge
Single sign-on
Reinvent the wheel is unsafe
From SOAP to REST
36. RESTful Security
Authorization
Define an access policy for the resources
For an authenticated user
May handle a guest user (public content)
Via Access Control Lists (ACL),
capabilities or groups
Following the principle of least privilege
Part of a trust chain (e.g. AD token, LDAP)
From SOAP to REST
38. mORMot’s REST
RESTful Local and Client-Server
In-process
Stand-alone client, fast server-side access
Named pipes or Windows messages
Stand-alone client, fast server-side access
HTTP/1.1 via kernel-mode http.sys API
Kernel-mode execution, IOCP driven – Windows specific
HTTP/1.1 via OS socket API
Windows or Linux
Upgradable to WebSockets
From SOAP to REST
39. mORMot’s REST
RESTful Local and Client-Server
In-process
Named pipes or Windows messages
HTTP/1.1 via kernel-mode http.sys API
Part of the OS since Windows XP SP2, used by IIS and WCF
Kernel-mode execution, IOCP driven
System-wide URI registration: share root and port
HTTP/1.1 via OS socket API
Cross platform Server and Client classes
Upgradable to WebSockets for asynchronous callbacks
From SOAP to REST
40. mORMot’s REST
REST design at class level
CRUD methods are inherited
TSQLRest.Retrieve() Add() Update() Delete()
Follows Liskov substitution principle
From SOAP to REST
TSQLRestServer
TSQLRest
TSQLRestClientURI
TSQLRestClient
41. mORMot’s REST
REST design at class level – Server side
Follows Open/Close principle
From SOAP to REST
TSQLRestServerDB
TSQLRestServer
TSQLRest
TSQLRestServerRemoteDB TSQLRestServerFullMemory
42. mORMot’s REST
REST design at class level – Server side
TSQLRestServerDB for SQLite3-powered storage
Embedded SQLite3 fast storage in single file database
Virtual tables for any external SQL / NoSQL database
TSQLRestServerFullMemory for fast RAM storage
Do not link the SQLite3 engine to the executable
Rely on efficient TObjectList class
Persisted as JSON or compressed binary file
Not persisted life business objects
TSQLRestServerRemoteDB for proxy access
Redirection to another REST Server for storage
From SOAP to REST
43. mORMot’s REST
REST design at class level – Server side
TSQLRestServerDB for SQLite3-powered storage
mORMot.pas mORMotSQLite3.pas SynSQlite3.pas
+ mORMotDB.pas mORMotMongoDB.pas
TSQLRestServerFullMemory for fast RAM storage
mORMot.pas
TSQLRestServerRemoteDB for proxy access
mORMot.pas
From SOAP to REST
44. mORMot’s REST
REST design at class level – Client side
Client classes are protocol-independent
Local and remote access share the same parent
From SOAP to REST
TSQLRestClientURINamedPipe
TSQLRestClientURI TSQLRestClient
TSQLRestClientURIMessage
TSQLRestClientURIDll
TSQLRestClientDB
TSQLHttpClientWinINet
TSQLHttpClientWinGeneric
TSQLHttpClientGeneric
TSQLHttpClientWinHTTP
TSQLHttpClientWinSockTSQLHttpClientCurl
TSQLRest
45. mORMot’s REST
REST design at class level – Client side
Several HTTP remote access classes
mORMotHttpClient.pas
From SOAP to REST
TSQLHttpClientWinINet
TSQLHttpClientWinGeneric
TSQLHttpClientGeneric
TSQLHttpClientWinHTTP
TSQLHttpClientWinSock TSQLHttpClientCurl
TSQLHttpClientWebsockets
49. mORMot’s REST
REST design – Cross-Platform Client side
Generated client code using Mustache templates
Delphi: Windows, MacOS, Android, iOS
FPC: Windows, MacOS, Android, iOS, Linux, …
(Cross)Kylix: Linux
SmartMobileStudio: Ajax / HTML5
Featuring almost all framework abilities
JSON marshalling, security, batch, TSQLRest class
From SOAP to REST
50. mORMot’s REST
Method-based services
Full access to the REST request
Linked to mORMot’s resources (ORM tables)
Defined as a published method
Parameters and JSON marshalling
Interface-based services are also available
From SOAP to REST
51. mORMot’s REST
Defining a method
type
TSQLRestServerTest = class(TSQLRestServerFullMemory)
(...)
published
procedure Sum(Ctxt: TSQLRestServerURIContext);
end;
Implementing a method
procedure TSQLRestServerTest.Sum(Ctxt: TSQLRestServerURIContext);
begin
with Ctxt do
Results([Input['a']+Input['b']]);
end;
From SOAP to REST
52. mORMot’s REST
Defining a method
type
TSQLRestServerTest = class(TSQLRestServerFullMemory)
(...)
published
procedure Sum(Ctxt: TSQLRestServerURIContext);
end;
Implementing a method
procedure TSQLRestServerTest.Sum(Ctxt: TSQLRestServerURIContext);
begin
Ctxt.Results([Ctxt['a']+Ctxt['b']]);
end;
From SOAP to REST
53. mORMot’s REST
Automatic URI and JSON content marshalling
For instance, the following request URI:
GET /root/Sum?a=3.12&b=4.2
will let our server method return:
{"Result":7.32}
That is, a perfectly AJAX-friendly request
With no restriction on the routing or marshalling
But not yet RESTful (where is the resource?)
From SOAP to REST
54. mORMot’s REST
Resource-based method
URI to execute this RESTful method will be:
GET root/People/1234/DataAsHex
From SOAP to REST
procedure TSQLRestServerTest.DataAsHex(Ctxt: TSQLRestServerURIContext);
var aData: TSQLRawBlob;
begin
if (self=nil) or (Ctxt.Table<>TSQLRecordPeople) or (Ctxt.TableID<=0) then
Ctxt.Error('Need a valid record and its ID') else
if RetrieveBlob(TSQLRecordPeople,Ctxt.TableID,'Data',aData) then
Ctxt.Results([SynCommons.BinToHex(aData)]) else
Ctxt.Error('Impossible to retrieve the Data BLOB field');
end;
56. mORMot’s REST
REST routing defined by classes
From SOAP to REST
TSQLRestRoutingJSON_RPC
TSQLRestServerURIContext
TSQLRestRoutingREST
TSQLRestServerURIContext = class
protected
...
function URIDecodeREST: boolean; virtual;
procedure URIDecodeSOAByMethod; virtual;
procedure URIDecodeSOAByInterface; virtual; abstract;
function Authenticate: boolean; virtual;
procedure ExecuteSOAByMethod; virtual;
procedure ExecuteSOAByInterface; virtual; abstract;
procedure ExecuteORMGet; virtual;
procedure ExecuteORMWrite; virtual;
...
57. mORMot’s REST
REST routing defined by classes
You can customize every aspect of the routing
for method-based services
JSON/RPC and REST are available by default
for interface-based services
Resource access via ORM is also customizable
From SOAP to REST
TSQLRestRoutingJSON_RPC
TSQLRestServerURIContext
TSQLRestRoutingREST
58. mORMot’s REST
HTTP Server
A single TSQLHttpServer can handle
one or several TSQLRestServer instances
Automated routing using TSQLModel.Root
Via http.sys or Sockets or WebSockets
mORMotHttpServer.pas
Advanced features
Virtual hosts, redirection, shared port (http.sys)
Deflate / SynLZ / AES compression/encryption
As application or service/daemon
From SOAP to REST
59. mORMot’s REST
Authentication
Modular and open: defined by classes
Safe (timed challenge, SHA-256)
Domain single sign-on via NTLM/SSPI
From SOAP to REST
TSQLRestServerAuthenticationSSPI
TSQLRestServerAuthenticationSignedURI
TSQLRestServerAuthenticationURI
TSQLRestServerAuthenticationDefault
TSQLRestServerAuthentication
TSQLRestServerAuthenticationNone
60. mORMot’s REST
Authorization
Resource-based
Customizable Users and Groups
Can be tuned via code
Integrated at framework core level
From SOAP to REST
ID : integer
AccessRights : RawUTF8
Ident : RawUTF8
SessionTimeout : integer
ID : integer
Data : TSQLRawBlob
DisplayName : RawUTF8
GroupRights : TSQLAuthGroup
LogonName : RawUTF8
PasswordHashHexa : RawUTF8
AuthGroup
61. mORMot’s JSON
JSON and UTF-8
UTF-8 from the ground up
UTF-8 is Unicode
Unicode even for Delphi < 2009, or FPC
Dedicated RawUTF8 string type for business logic
JSON used for transmission and internal storage
for client-server ORM and SOA
e.g. for cache on server or client side
direct in-place parsing to avoid memory allocation
From SOAP to REST
62. mORMot’s JSON
UTF-8 JSON from the ground up
Optimized functions and classes (TTextWriter)
Bypass the RTL on purpose (e.g. Win64, FPC)
SynCommons.pas unit shared by ORM, SynDB, SOA
Universal mean of transmission and storage
Extended types (date/time, blob, BSON)
Dynamic array, record, class and variant
TDocVariant custom type for late-binding
From SOAP to REST
63. mORMot’s JSON
Dynamic array wrapper
TDynArray gives access
to any existing dynamic array
via high-level methods
Count / Add / Delete / Find …
TDynArrayHashed add hash-based
fast O(1) search of item values
External Count variable for much faster adding
Binary and JSON serialization
From SOAP to REST
64. mORMot’s JSON
TDocVariant custom type
Stores any transient value as document:
Object
Array
Any nested combination of the two
Low memory overhead
Data allocation per blocks of variants
Copy by reference can be enabled
Instance lifetime managed by the compiler
Direct JSON support
Late-binding magic
From SOAP to REST
65. mORMot’s JSON
Create TDocVariant instances
TDocVariant.New()
_Obj() _ObjFast()
_Arr() _ArrFast()
_Json() _JsonFast() _JsonFmt() _JsonFastFmt()
_*() for per-value instances
will copy the whole document content
_*Fast() for per-reference instances
will copy a reference of the document content
From SOAP to REST
66. mORMot’s JSON
TDocVariant custom type
var V: variant; // stored as any variant
...
TDocVariant.New(V); // or slightly slower V := TDocVariant.New;
V.name := 'John'; // property accessed via late-binding
V.year := 1972;
// now V contains {"name":"john","year":1972}
var V1,V2: variant;
...
V1 := _Obj(['name','John','year',1972]);
V2 := _Obj(['name','John','doc',_Obj(['one',1,'two',2.5])]);
V1 := _Json('{"name":"John","year":1982}');
V2 := _Json('{name:"John",doc:["one",1,"two",2.5]}');
From SOAP to REST
67. mORMot’s JSON
TDocVariant custom type
writeln('name=',V1.name,' year=',V1.year);
// will write 'name=John year=1972'
writeln('name=',V2.name,' doc.one=',V2.doc.one,' doc.two=',doc.two);
// will write 'name=John doc.one=1 doc.two=2.5
V1.name := 'Mark'; // overwrite a property value
writeln(V1.name); // will write 'Mark'
V1.age := 12; // add a property to the object
writeln(V1.age); // will write '12'
writeln(V1); // implicit conversion to string -> as JSON
// will write '{"name":"Mark","year":1972,"age":12}'
writeln(VariantSaveJSON(V1)); // serialize as RawUTF8 JSON
From SOAP to REST
68. mORMot’s JSON
TDocVariant custom type
Pseudo-methods:
_Json/_Count/_Kind for objects
Add/Delete/Count/_ for arrays
var V: variant;
...
V := _Json('{arr:[1,2]}');
writeln(V._Count); // will write 1 (one property in the V object)
V.arr.Add(3); // will work, since V.arr is returned by reference (varByRef)
writeln(V); // will write '{"arr":[1,2,3]}'
V.arr.Delete(1);
writeln(V); // will write '{"arr":[1,3]}‘
From SOAP to REST
69. mORMot’s JSON
BSON Support
For fast direct MongoDB access
Extended JSON
{id:new ObjectId(),doc:{name:"John",date:ISODate()}}
{name:"John",field:/acme.*corp/i}
TBsonVariant custom type
Supporting all BSON types and Late-binding
Integrated with TDocVariant
SynMongoDB.pas
From SOAP to REST
70. From SOAP to REST
… back to mORMot SOA implementation