EKON20 Conference, November 2016
Monolithic rich Windows applications are not enough for our customers. We are often requested to provide a web front-end, or a REST server to be consumed by mobile or thin clients. Integrating n-Tier architecture to an existing project is challenging. Some good practices, based on industry standards and proven design patterns (like uncoupling or SOLID) can be mind-breaker for RAD developers. In this session, we will define some architectural aspects of SOA, ORM and MVC/MVVM, and what our Open Source mORMot framework offers to ease this transition.
Strategies for using alternative queries to mitigate zero results
Ekon20 mORMot SOA Delphi Conference
1. Arnaud Bouchez | Synopse
From RAD to SOA
with mORMot
20161107T101500 - 20161107T113000
2. From RAD to SOA
with mORMot
• Notions
– Design
RAD, OOP, SOLID, DDD
– Architecture
2-Tier, 3-Tier, SOA, MicroServices
3. From RAD to SOA
with mORMot
• Customer-focused Architecture
• Implicit BBM Architecture
• Is it worth it?
• N-Tier
• SOA
• mORMot to the rescue
4. Customer-focused Architecture
• You can't talk about architecture
in isolation
• Architecture is always driven
by the actual needs
of the application
5. Customer-focused Architecture
• There is no such "one architecture fits all"
nor "one framework fits all" solution
• Architecture is just a thinking of
how you are building your own software
• Design is architecture applied in code
6. Customer-focused Architecture
• is not about theory and diagrams
• nor just about best practice
• but an attempt to find
– a way of implementing
– a working solution
– for your customers
8. Customer-focused Architecture
• Premature architecture
may be the root of all evil (as optimization is)
• But no architecture, nor abstraction,
will close many doors, and let maintainability
be a nightmare, even impossible
9. Implicit BBM Architecture
• No Architecture?
• Will end with an implicit architecture
• Big Ball of Mud (BBM) design pattern
13. Design
• RAD
Quick and efficient via components
• OOP
Business separated from UI
• SOLID
Proper classes & interfaces
• DDD
Uncouple your Domain
14. Design - TDD
• RAD
Manual testing
• OOP
System testing
• SOLID
Injection allow proper unit testing
• DDD
Testing from isolation
15. Design – Long Term
• RAD
Fast to write, difficult to maintain
• OOP
Dependencies between classes
• SOLID
Agility through Uncoupling and IoC
• DDD
Safe and sound Domain
30. N-Tier
• Logical and Physical Views
Most of the time, n-Tier is intended
to be a physical (hardware) view
– e.g. separation between the database server
and the application server
– placing any tier on a separate machine
to facilitate ease of maintenance
or integrate with IT/SaaS requirements
31. N-Tier
• Logical and Physical Views
In SOA, we deal with logical layout
– Separation of layers through logic interfaces
– Underlying hardware implementation may,
but will usually not, match the logical layout
36. N-Tier
• Logical View
• Web app
Client & Server
• SQL Database
with stored procedures
Application Tier
Data Tier
37. N-Tier
• Logical and Physical Views
Presentation Tier
Application Tier
Business Logic Tier
Data Tier
Client 1 (Delphi) Client 2 (AJAX)
Application Server
DB Server
Presentation Tier
Application Tier
Presentation Tier
Business Logic Tier
Data Tier
40. SOA
• Service-Oriented Architecture
– The SOA implementations rely
on a mesh of uncoupled software services
– Software Service:
• A consumer asks a producer
to act in order to produce a result
• Invocation is (often) free from previous invocation
(stateless), to minimize resource consumption
41. SOA
• Service-Oriented Architecture
– The SOA implementations rely
on a mesh of uncoupled software services
– Those Services comprise
• unassociated, loosely coupled
units of functionality
(each service implements one action)
• that have no direct call to each other
(via protocols, catalogs over a bus)
42. SOA
• Service-Oriented Architecture
– The SOA implementations rely
on a mesh of uncoupled software services
Consumers Service Bus Publishers
Client A Publisher 1
Publisher 2Client B
Publisher 3Client C
Service 1
Service 2
Service 3
43. SOA
• Service-Oriented Architecture
– The SOA implementations rely
on a mesh of uncoupled software services
– Service composition
• Logical multi-tier orchestration (transactional)
• A higher level service invokes several services
• Works as a self-contained, stateless service
• Lower-level services can still be stateless
• E.g. application services over business services
44. SOA
• Service-Oriented Architecture
– The SOA implementations rely
on a mesh of uncoupled software services
– Service composition
Consumers Application Service Bus Application Publishers
Business Service Bus Business Publishers
Client A
Composition
Publisher
Composition
Service
Publisher 1
Publisher 2
Publisher 3
Service 1
Service 2
Service 3
45. SOA
• SOA is mainly about decoupling
• It enables implementation independence
in a variety of ways
– Platform
– Location
– Availability
– Versions
46. SOA
• SOA is mainly about decoupling
Dependency Desired decoupling Decoupling technique
Platform
Hardware, Framework or Operating
System should not constrain choices
of the Services consumers
Standard protocols, mainly Web
services (e.g. SOAP or RESTful/JSON)
Location
Consumers may not be impacted by
service hosting changes
Routing and proxies will maintain
Services access
Availability
Maintenance tasks shall be
transparent
Remote access allows centralized
support on Server side
Versions
New services shall be introduced
without requiring upgrades of clients
Contract marshaling can be
implemented on the Server side
48. SOA
• Micro Services
– SOLID principles meet SOA
• Single responsibility principle
• Open/closed principle
• Liskov substitution principle (design by contract)
• Interface segregation principle
• Dependency inversion principle
49. SOA
• Micro Services
• Single responsibility principle
Object should have only a single axis of change
• Open/closed principle
Open for extension, but closed for modification
• Liskov substitution principle (design by contract)
Replaceable with subtypes without breaking the contract
• Interface segregation principle
Many specific classes/interfaces are better than one
• Dependency inversion principle
Depend upon abstractions not concretion, using injection
50. SOA
• Micro Services
– SOLID principles meet SOA
– Favor stateless calls, and/or event-driven
– Implemented as stand-alone nodes
– Enhance scaling abilities
– Expects services discovery
51. SOA
• Favor logical Multi-tier architecture
• Put business intelligence on the server side
• Use less bandwidth than a fat client
• From fat client to rich clients (new platforms)
• Leverage resources (DB, cache)
• Easier to upgrade
• Cheaper / Safer for the customer (backup, cloud)
52. SOA
• Expects a top/down implementation
– Don’t start from the DB, but end-user app
• Forget about bottom/up design
• Define services, not data structures
– Ability to uncouple things
• Identify bounded contexts and needed information
53. SOA
• Expects a top/down implementation
– Modelize your business in reusable services
• Interfaces and explicit types (DTO) everywhere
• Focus on domain to build tools and maximize ROI
– Cross-cutting features may be delegated
• Emailing, CRM, billing, reporting, UI…
• If this is not where money comes from
54. SOA
• Expects a top/down implementation
– From n-Tier vertical Architecture
• DB as Root
• Business over DB
– to Clean “onion” Architecture
• Domain as Core
• Persistence as a service
57. SOA with mORMot
• Services can be implemented as:
– Method-based resource-focused services
– Interface-based services
• RESTful architecture
– Over several protocols, e.g. HTTP/1.1
– JSON and UTF-8 based
• KISS / CoC design
58. SOA with mORMot
• Method-based services
type
TSQLRestServerTest = class(TSQLRestServerFullMemory)
(...)
published
procedure Sum(Ctxt: TSQLRestServerURIContext);
end;
procedure TSQLRestServerTest.Sum(Ctxt: TSQLRestServerURIContext);
begin
with Ctxt do
Results([Input['a']+Input['b']]);
end;
59. SOA with mORMot
• Method-based services
type
TSQLRestServerTest = class(TSQLRestServerFullMemory)
(...)
published
procedure Sum(Ctxt: TSQLRestServerURIContext);
end;
procedure TSQLRestServerTest.Sum(Ctxt: TSQLRestServerURIContext);
begin
Ctxt.Results([Ctxt['a']+Ctxt['b']]);
end;
60. SOA with mORMot
• Method-based services
type
TSQLRestServerTest = class(TSQLRestServerFullMemory)
(...)
published
procedure Sum(Ctxt: TSQLRestServerURIContext);
end;
by convention, accessible e.g. from
http://server/root/sum?a=123&b=456
where root comes from REST server model
61. SOA with mORMot
• Method-based services
– Give full access to the request
• e.g. 30# replies or static content delivery
– Manual marshalling, e.g. for parameters
• on the server side (error prone)
• on the client side (dedicated code to write)
– Still too close to the metal
62. SOA with mORMot
• Interface-based services
– Follow Delphi native abstraction of interface
• Strong naming and typing
• Parameters are marshaled via method signature
• SOLID abstractions
• Reference-counted memory management
• Optional dual-way callbacks (WebSockets)
63. SOA with mORMot
• Interface-based services
– Client-side wrapper is generated at runtime
• Features RESTful UTF-8 JSON, so AJAX ready
– Tied to mORMot’s REST and security model
• From stand-alone app to complex MicroServices
• Easily integrated with stubbing/mocking features
64. SOA with mORMot
• Interface-based services steps:
– Define a contract
– Implement the contract on server side
– Host and publish the service
– Access the service from client side
65. SOA with mORMot
• Define a contract
type
ICalculator = interface(IInvokable)
['{9A60C8ED-CEB2-4E09-87D4-4A16F496E5FE}']
/// add two signed 32 bit integers
function Add(n1,n2: integer): integer;
end;
• ICalculator interface defines the contract
• Add() method defines the operation
• Handle any kind of parameters
– Including classes, variants, dynamic arrays or records
66. SOA with mORMot
• Implement the contract on server side
type
TServiceCalculator = class(TInterfacedObject, ICalculator)
public
function Add(n1,n2: integer): integer;
end;
function TServiceCalculator.Add(n1, n2: integer): integer;
begin
result := n1+n2;
end;
… and that’s all !
67. SOA with mORMot
Host and publish the service
Server.ServiceRegister(
TServiceCalculator,[TypeInfo(ICalculator)],sicShared);
– will register the TServiceCalculator class
– to implement the ICalculator service
– with a single shared instance life time
– to any TSQLRestServer instance
68. SOA with mORMot
Host and publish the service
Server.ServiceRegister(
TServiceCalculator,[ICalculator],sicShared);
– will register the TServiceCalculator class
– to implement the ICalculator service
– with a single shared instance life time
– to any TSQLRestServer instance
69. SOA with mORMot
Access the service from client side
Client.ServiceDefine([ICalculator],sicShared);
• Register to any kind of TSQLRestClient
via named pipes, messages, HTTP, WebSockets
• Execution will take place on the server side
• ICalculator type defines the contract
70. SOA with mORMot
Access the service from client side
var I: ICalculator;
begin
if Client.Services['Calculator'].Get(I) then
result := I.Add(10,20);
end;
• A “fake” class implements ICalculator
• Data is transmitted by representation as JSON / REST
• Any server-side exception will be transmitted back
71. SOA with mORMot
Access the service from client side
var I: ICalculator;
begin
if Client.Services.Resolve(ICalculator,I) then
result := I.Add(10,20);
end;
• Implements IoC / DI patterns
• You can inject other local (mocked) services
72. SOA with mORMot
Access the service from server side
var I: ICalculator;
begin
if Server.Services.Resolve(ICalculator,I) then
result := I.Add(10,20);
end;
• Direct in-process execution
• Service composition with no performance penalty
• Business logic uncoupled from actual execution
73. SOA with mORMot
• Interface-based services instance lifetime
Lifetime Use case
sicSingle An asynchronous process (may be resource consuming)
sicShared Either a very simple process, or requiring some global data
sicClientDriven
The best candidate to implement a Business Logic workflow
and light transactional process (Unit-Of-Work pattern)
sicPerSession To maintain some data specific to the client application
sicPerUser Access to some data specific to one user
sicPerGroup
Access to some data shared by a user category
(e.g. administrators, or guests)
sicPerThread Thread-oriented process (e.g. for proper library initialization)
74. SOA with mORMot
• Interface-based services routing
– Classes available by default:
– you can define your own class
TSQLRestRoutingREST TSQLRestRoutingJSON_RPC
Description RESTful mode JSON-RPC mode
Default Yes No
URI scheme
/Model/Interface.Method[/ClientDrivenID]
or /Model/Interface/Method[/ClientDrivenID]
+ optional URI-encoded params
/Model/Interface
Body content
JSON array (or object) of parameters
or void if parameters were encoded at URI
{"method":"MethodName",
"params":[...]
[,"id":ClientDrivenID]}
Security
RESTful authentication for each method
or for the whole service (interface)
RESTful authentication for the
whole service (interface)
75. SOA with mORMot
• Interface-based services execution modes
– Per-method threading behavior
TServiceMethodOptions Description
none (default)
All methods are re-entrant and shall be coded to be thread-safe
(best scaling performance, but may be error prone)
optExecLockedPerInterface Each interface will be protected/locked by its own mutex
optExecInMainThread
optFreeInMainThread
Methods will be executed in the process main thread
Interface will be released in the process main thread
optExecInPerInterfaceThread
optFreeInPerInterfaceThread
Each interface will execute its methods in its own thread
Each interface will be freed in its own thread
76. SOA with mORMot
Interface-based services Security
– Based on framework’s RESTful authentication
– Expects a user to be authenticated
and an in-memory session to be initiated
77. SOA with mORMot
Interface-based services Security
– Based on framework’s RESTful authentication
– Restrain execution via fluent interface, e.g.
Server.ServiceDefine(
TServiceCalculator,ICalculator,sicShared).
DenyAll.
AllowAllByName(['Supervisor']);
78. SOA with mORMot
• Interface-based services callbacks
– Specify the callback as an interface parameter
• Native way of coding
– Real-time push notifications over WebSockets
• Upgraded from a standard HTTP connection
– Peer To Peer communication
• No need of a centralized message bus / server
79. SOA with mORMot
• Interface-based services callbacks
– Specify the callback as an interface parameter
ILongWorkCallback = interface(IInvokable)
['{425BF199-19C7-4B2B-B1A4-A5BE7A9A4748}']
procedure WorkFinished(const workName: string;
timeTaken: integer);
procedure WorkFailed(const workName, error: string);
end;
80. SOA with mORMot
• Interface-based services callbacks
– Specify the callback as an interface parameter
ILongWorkCallback = interface(IInvokable)
…
ILongWorkService = interface(IInvokable)
['{09FDFCEF-86E5-4077-80D8-661801A9224A}']
procedure StartWork(const workName: string;
const onFinish: ILongWorkCallback);
function TotalWorkCount: Integer;
end;
81. SOA with mORMot
• Interface-based services callbacks
– Real-time push notifications over WebSockets
82. SOA with mORMot
• Interface-based services callbacks
– Real-time push notifications over WebSockets
• Once upgraded, communicates using frames
over a bi-directional socket connection
using application-level protocols
• Security, frames gathering, REST emulation,
binary encryption and compression
83. SOA with mORMot
• Cross-platform Interface-based services
– Generated client code
• Using Mustache templates
• Delphi: Windows, MacOS, Android, iOS
• FPC: Windows, MacOS, Android, iOS, Linux, …
• (Cross)Kylix: Linux
• SmartMobileStudio, EWB: Ajax / HTML5
– Featuring almost all framework abilities
• JSON marshalling, security, instance lifetime
84. SOA with mORMot
• REST design at class level
Following SOLID principles
TSQLRestServer
TSQLRest
TSQLRestClientURI
TSQLRestClient
89. SOA with mORMot
• Interface-based services callbacks
– Sample 31
• Long-Work Push Notification
also known as “Sagas”
• Publish/Subscribe Pattern
also known as “Observer”
90. SOA with mORMot
• Resources
– http://synopse.info
– http://synopse.info/forum
– http://blog.synopse.info
– http://github.com/synopse/mORMot
Includes exhaustive documentation,
samples and regression tests.