April 2014RSI
From SOAP to RESTArnaud Bouchez
April 2014RSI
From SOAP to REST
SOAP REST JSON Security practice
From SOAP to REST
April 2014RSI
Simple Object Access Protocol
SOAP XML WSDL Defines
Processing model Extensibility model Underlying protocol binding Message construct
From SOAP to REST
April 2014RSI
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
April 2014RSI
REST
From SOAP to REST
April 2014RSI
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
And share the same author as HTTP(Roy Fielding)
From SOAP to REST
April 2014RSI
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
April 2014RSI
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
April 2014RSI
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
April 2014RSI
REST Unique Identifier Some URI samples:
Get Customer details with name “dupont”
http://www.mysite.com/Customer/dupont
Get Customer details with name “smith”
http://www.mysite.com/Customer/smith
Get orders placed by customer “dupont”
http://www.mysite.com/Customer/dupont/orders
From SOAP to REST
April 2014RSI
REST Interfaces
Access those identified resourcesvia basic CRUD activity identified by a set of HTTP verbs GET Read PUT Update POST Create DELETE Delete
From SOAP to REST
April 2014RSI
REST Interfaces
Combination of HTTP method and URI replace a list of English-based methods, like GetCustomer / InsertCustomer / UpdateOrder / RemoveOrder
From SOAP to REST
April 2014RSI
REST Interfaces
From SOAP to REST
April 2014RSI
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
April 2014RSI
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"}}
April 2014RSI
JSON
JavaScript Object Notation (JSON) standard open and lightweight
text-based, human-readable formatfor representing simple data structures and associative arrays (called objects)
From SOAP to REST
April 2014RSI
JSON types
Number 123.45 String “text” Boolean true/false Array [ ] Object { } Null null
+ non significant white spaces
From SOAP to REST
April 2014RSI
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
April 2014RSI
<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
April 2014RSI
JSON/XML alternatives
Text INI TOML YAML
Binary BSON MessagePack Protocol Buffers WCF
From SOAP to REST
April 2014RSI
RESTful Security
Security in Client-Server is usually implemented by: Process safety Authentication Authorization
From SOAP to REST
April 2014RSI
RESTful Security
Process safety Code quality Testing Feedback, peer review Transmission encryption Do not reinvent the wheel
From SOAP to REST
April 2014RSI
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
April 2014RSI
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
April 2014RSI
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
April 2014RSI
RESTful Security
Authentication patterns
Password stored as hash N-way challenge Single sign-on Reinvent the wheel is unsafe
From SOAP to REST
April 2014RSI
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
April 2014RSI
mORMot’s REST
From SOAP to REST
April 2014RSI
mORMot’s REST
RESTful Client-Server In-process
Stand-alone client, fast server-side access
Named pipes or GDI messages Stand-alone client, fast server-side access
HTTP/1.1 via kernel-mode http.sys API Part of the OS since Windows XP SP2 Kernel-mode execution, IOCP driven System-wide URI registration: share root and port Used by IIS and WCF Socket-based server is also available
From SOAP to REST
April 2014RSI
mORMot’s REST
REST design at class level
CRUD methods are inherited Follows Liskov substitution principle
TSQLRestServer
TSQLRest
TSQLRestClientURI
TSQLRestClient
April 2014RSI
mORMot’s REST
REST design at class level – Server side
Follows Open/Close principle
From SOAP to REST
TSQLRestServerDB
TSQLRestServer
TSQLRest
TSQLRestServerRemoteDB TSQLRestServerFullMemory
April 2014RSI
mORMot’s REST
REST design at class level – Server side TSQLRestServerDB for embedded SQLite3 code
For fast storage in a standard one-file database Virtual tables allow to access any external RDBMS
TSQLRestServerFullMemory for fast RAM storage Do not link the SQLite3 engine to the executable Rely on a efficient TObjectList class Persisted as JSON or compressed binary file
TSQLRestServerRemoteDB for proxy access
From SOAP to REST
April 2014RSI
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
TSQLRestClientDBTSQLHttpClientWinINet
TSQLHttpClientWinGeneric
TSQLHttpClientGenericTSQLHttpClientWinHTTP
TSQLHttpClientWinSock
TSQLRest
April 2014RSI
mORMot’s REST
JSON and UTF-8 UTF-8 from the ground up
UTF-8 is Unicode Unicode even for Delphi < 2009 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
allocationFrom SOAP to REST
April 2014RSI
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
April 2014RSI
mORMot’s REST
Defining a methodtype TSQLRestServerTest = class(TSQLRestServerFullMemory) (...) published procedure Sum(Ctxt: TSQLRestServerURIContext); end;
Implementing a methodprocedure TSQLRestServerTest.Sum(Ctxt: TSQLRestServerURIContext);begin with Ctxt do Results([Input['a']+Input['b']]);end;
From SOAP to REST
April 2014RSI
mORMot’s REST
Automatic URI and JSON content marshalling For instance, the following request URI:
GET /root/Sum?a=3.12&b=4.2will 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 fully RESTful (where is the
resource?)From SOAP to REST
April 2014RSI
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;
April 2014RSI
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; ...
April 2014RSI
mORMot’s REST
REST routing defined by classes
You can customize every aspect of the routingfor method-based services
JSON/RPC and REST are available by defaultfor interface-based services
Resource access via ORM is also customizable
From SOAP to REST
TSQLRestRoutingJSON_RPC
TSQLRestServerURIContext
TSQLRestRoutingREST
April 2014RSI
mORMot’s REST
Authentication Modular and open: defined by classes Safe (timed challenge, SHA-256) Single sign-on via NTLM
From SOAP to REST
TSQLRestServerAuthenticationSSPI
TSQLRestServerAuthenticationSignedURI
TSQLRestServerAuthenticationURI
TSQLRestServerAuthenticationDefault
TSQLRestServerAuthentication
TSQLRestServerAuthenticationNone
April 2014RSI
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 : integerAccessRights : RawUTF8
Ident : RawUTF8SessionTimeout : integer
ID : integerData : TSQLRawBlob
DisplayName : RawUTF8GroupRights : TSQLAuthGroup
LogonName : RawUTF8PasswordHashHexa : RawUTF8
AuthGroup
April 2014RSI
mORMot’s JSON
UTF-8 JSON from the ground up Optimized functions and classes
(TTextWriter) Bypass the RTL on purpose (e.g. Win64) SynCommons.pas unit shared by ORM, SynDB,
SOA Universal mean of transmission and storage Extended types (dates, BLOB) Dynamic arrays and variants support TDocVariant custom type for late-binding
From SOAP to REST
April 2014RSI
mORMot’s JSON
Dynamic array wrapper TDynArray gives access
to any existing dynamic arrayvia high-level methodsCount / Add / Delete / Find …
TDynArrayHashed add hash-basedfast O(1) search of item values
External Count variable for much faster adding
Binary and JSON serialization
From SOAP to REST
April 2014RSI
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
April 2014RSI
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
April 2014RSI
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
April 2014RSI
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
April 2014RSI
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
April 2014RSI
From SOAP to REST
Thanks to Bill Meyer for his review
Any feedback is welcome athttp://synopse.info