Download as pdf or txt
Download as pdf or txt
You are on page 1of 68

From SOAP to REST

Arnaud Bouchez
June 2015
From SOAP to REST
 SOAP
 REST
 JSON
 Security
 practice

From SOAP to REST


June 2015
Simple Object Access Protocol
 SOAP
 XML

 WSDL

 Defines
 Processing model
 Extensibility model
 Underlying protocol binding
 Message construct

From SOAP to REST


June 2015
Simple Object Access Protocol
 
 Standard

 Feature complete
 Time proof

From SOAP to REST


June 2015
Simple? Object Access Protocol
 
 Standard

 Feature complete
 Time proof

 
 Severalimplementations (1.0/1.1/WCF/J2EE)
 Verbose and heavy (slow)

 Complex

From SOAP to REST


June 2015
REST

From SOAP to REST


June 2015
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


June 2015
REpresentational State Transfer
 Share the 5 basic fundamentals of the web…
 And share the same author as HTTP
(Roy Fielding)

From SOAP to REST


June 2015
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
 RESTdoes not define nor expect anything like
headers, sessions, cookies, https

From SOAP to REST


June 2015
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


June 2015
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


June 2015
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


 Infact, every URI should uniquely
represent one item of the data collection

From SOAP to REST


June 2015
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


June 2015
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


June 2015
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


June 2015
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


June 2015
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


June 2015
REST Interfaces

From SOAP to REST


June 2015
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


June 2015
REST transfert by Representation

 What you are sending over the wire


is in fact a Representation
of the actual resource data
<Customer>
 As XML <ID>1234</ID>
<Name>Dupond</Name>
<Address>Tree street</Address>
</Customer>

{"Customer":
 As JSON {"ID":1234, "Name":"Dupond", "Address":"Tree street"}}

From SOAP to REST


June 2015
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
<Customer>
 As XML <ID>1234</ID>
<Name>Dupond</Name>
<Address>Tree street</Address>
</Customer>

{"Customer":
 As JSON {"ID":1234, "Name":"Dupond", "Address":"Tree street"}}

From SOAP to REST


June 2015
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


June 2015
JSON types
 Number 123.45
 String "text"
 Boolean true/false
 Array [ ]
 Object { }
 Null null
+ non significant white spaces

From SOAP to REST


June 2015
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


June 2015
JSON sample
{
"firstName": "John",
"lastName": "Smith",
"age": 25,
"address": {
"streetAddress": "21 2nd Street",
"city": "New York",
"state": "NY",
"postalCode": 10021
},
"phoneNumbers": [
{
"type": "home",
"number": "212 555-1234"
},
{
"type": "fax",
"number": "646 555-4567"
};
]
}

From SOAP to REST


June 2015
<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


June 2015
JSON/XML alternatives
 Text
 INI
 TOML
 YAML

 Binary
 BSON
 MessagePack
 Protocol Buffers
 WCF

From SOAP to REST


June 2015
RESTful Security
 Security in Client-Server
is usually implemented by:
 Process safety

 Authentication

 Authorization

From SOAP to REST


June 2015
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


June 2015
RESTful Security
 Process safety
 Code quality
 Risk management

 Testing

 Feedback, peer review

 Transmission encryption

 Do not reinvent the wheel

From SOAP to REST


June 2015
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


June 2015
RESTful Security
 RESTful Authentication
 HTTP basic auth over HTTPS
 Not user-friendly (weird popup)
 Password is transmitted

 Cookies and session management


 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


June 2015
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&timestamp=1261496500"
and the signature is the SHA-256 hash of that string
using the private component of the API key.

From SOAP to REST


June 2015
RESTful Security
 Authentication patterns
 Password stored as hash
 N-way challenge

 Single sign-on

 Reinvent the wheel is unsafe

From SOAP to REST


June 2015
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


June 2015
mORMot’s REST

From SOAP to REST


June 2015
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


June 2015
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


June 2015
mORMot’s REST
 REST design at class level
TSQLRestClientURI

TSQLRestServer TSQLRestClient

TSQLRest

 CRUD methods are inherited


 TSQLRest.Retrieve() Add() Update() Delete()
 Follows Liskov substitution principle

From SOAP to REST


June 2015
mORMot’s REST
 REST design at class level – Server side

TSQLRestServerDB TSQLRestServerRemoteDB TSQLRestServerFullMemory

TSQLRestServer

TSQLRest

 Follows Open/Close principle

From SOAP to REST


June 2015
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


June 2015
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


June 2015
mORMot’s REST
 REST design at class level – Client side
TSQLRestClientURINamedPipe

TSQLRestClientURIMessage

TSQLRestClientURIDll TSQLRestClientURI TSQLRestClient TSQLRest


TSQLHttpClientWinINet
TSQLRestClientDB
TSQLHttpClientWinHTTP TSQLHttpClientWinGeneric
TSQLHttpClientGeneric
TSQLHttpClientCurl TSQLHttpClientWinSock

 Clientclasses are protocol-independent


 Local and remote access share the same parent

From SOAP to REST


June 2015
mORMot’s REST
 REST design at class level – Client side
TSQLHttpClientWinINet TSQLHttpClientWinHTTP TSQLHttpClientWebsockets

TSQLHttpClientWinGeneric TSQLHttpClientWinSock TSQLHttpClientCurl

TSQLHttpClientGeneric

 Several HTTP remote access classes


 mORMotHttpClient.pas

From SOAP to REST


June 2015
mORMot’s REST

From SOAP to REST


June 2015
mORMot’s REST

From SOAP to REST


June 2015
mORMot’s REST

From SOAP to REST


June 2015
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, TSQLRest class

From SOAP to REST


June 2015
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


June 2015
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


June 2015
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


June 2015
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


June 2015
mORMot’s REST
 Resource-based method
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;

 URI to execute this RESTful method will be:


GET root/People/1234/DataAsHex

From SOAP to REST


June 2015
mORMot’s REST
 REST routing defined by classes
TSQLRestRoutingJSON_RPC TSQLRestRoutingREST

TSQLRestServerURIContext

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;
...

From SOAP to REST


June 2015
mORMot’s REST
 REST routing defined by classes
TSQLRestRoutingJSON_RPC TSQLRestRoutingREST

TSQLRestServerURIContext

 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


June 2015
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


June 2015
mORMot’s REST
 Authentication
 Modular and open: defined by classes
 Safe (timed challenge, SHA-256)

 Domain single sign-on via NTLM/SSPI


TSQLRestServerAuthenticationSSPI TSQLRestServerAuthenticationDefault

TSQLRestServerAuthenticationSignedURI TSQLRestServerAuthenticationNone

TSQLRestServerAuthenticationURI

TSQLRestServerAuthentication

From SOAP to REST


June 2015
mORMot’s REST
 Authorization
 Resource-based

 Customizable Users and Groups


 Can be tuned via code

 Integrated at framework core level

ID : integer
Data : TSQLRawBlob
DisplayName : RawUTF8
ID : integer
GroupRights : TSQLAuthGroup AuthGroup
AccessRights : RawUTF8
LogonName : RawUTF8
Ident : RawUTF8
PasswordHashHexa : RawUTF8
SessionTimeout : integer

From SOAP to REST


June 2015
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


June 2015
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


June 2015
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


June 2015
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


June 2015
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


June 2015
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


June 2015
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


June 2015
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


June 2015
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


June 2015
From SOAP to REST
June 2015

You might also like