Configuration
A WiRL application is basically an HTTP server with a routing system that follows the REST specification. The core of the application is the Engine that handles all the HTTP requests and sends each one to the right sub-module called Application. Each application has its own resources and filters used to process the requests.
Fluent interface
To configure WiRL you can use the fluent interface style. The configuration methods return always the Self object so you can call another configuration method on the Result itself. The main advantage of this technique is to avoid to declare object and sub objects only to configure them.
Let me show you an example of the configuration using the fluent interface or a more "classic" style:
procedure TMainForm.ConfigureServerFluent(AServer: TWiRLServer);
begin
// Server & Apps configuration
AServer
.SetPort(StrToIntDef(PortNumberEdit.Text, 8080))
// Engine configuration
.AddEngine<TWiRLEngine>('/rest')
.SetEngineName('WiRL Auth Demo')
// App base configuration
.AddApplication('/app')
.SetAppName('Auth Application')
.SetResources([
'Server.Resources.TFormAuthResource',
'Server.Resources.TBasicAuthResource',
'Server.Resources.TBodyAuthResource',
'Server.Resources.TUserResource'
])
// Auth configuration
.Plugin.Configure<IWiRLConfigurationAuth>
.SetTokenType(TAuthTokenType.JWT)
.SetTokenLocation(TAuthTokenLocation.Bearer)
.BackToApp
// JWT configuration (App plugin configuration)
.Plugin.Configure<IWiRLConfigurationJWT>
.SetClaimClass(TServerClaims)
.SetAlgorithm(TJOSEAlgorithmId.HS256)
.SetSecret(TEncoding.UTF8.GetBytes(edtSecret.Text))
;
end;
procedure TMainForm.ConfigureServer(AServer: TWiRLServer);
var
LEngineConf: TWiRLEngine;
LAppConf: IWiRLApplication;
LAuthConf: IWiRLConfigurationAuth;
LJWTConf: IWiRLConfigurationJWT;
begin
// Server & Apps configuration
AServer.SetPort(StrToIntDef(PortNumberEdit.Text, 8080));
// Engine configuration
LEngineConf := AServer.AddEngine<TWiRLEngine>('/rest');
LEngineConf.SetEngineName('WiRL Auth Demo');
// App base configuration
LAppConf := LEngineConf.AddApplication('/app');
LAppConf.SetAppName('Auth Application');
LAppConf.SetResources([
'Server.Resources.TFormAuthResource',
'Server.Resources.TBasicAuthResource',
'Server.Resources.TBodyAuthResource',
'Server.Resources.TUserResource'
]);
// Auth configuration
LAuthConf := LAppConf.Plugin.Configure<IWiRLConfigurationAuth>;
LAuthConf.SetTokenType(TAuthTokenType.JWT);
LAuthConf.SetTokenLocation(TAuthTokenLocation.Bearer);
// JWT configuration (App plugin configuration)
LJWTConf := LAppConf.Plugin.Configure<IWiRLConfigurationJWT>;
LJWTConf.SetClaimClass(TServerClaims);
LJWTConf.SetAlgorithm(TJOSEAlgorithmId.HS256);
LJWTConf.SetSecret(TEncoding.UTF8.GetBytes(edtSecret.Text));
end;
This configuration defines an application that answers to URLs like this:
http://localhost:8080/rest/app/<resource_path>
CurrentApp, CurrentEngine, BackToApp
Even using the fluent interface when we want to configure more that one engine or app you are forced to save (and declare) the Engine and App objects. To avoid cluttering the configuration code you can use the utility methods:
// Server & Apps configuration
AServer
.SetPort(StrToIntDef(PortNumberEdit.Text, 8080))
// Engine configuration
.AddEngine<TWiRLEngine>('/rest')
.SetEngineName('WiRL Auth Demo')
// First App
.AddApplication('/auth_app')
.SetAppName('Auth Application')
.SetResources('*');
AServer
.CurrentEngine<TWiRLEngine>
// App base configuration
.AddApplication('/prod_app')
.SetAppName('Production Application')
.SetResources('*')
;
Engines
Every WiRL server should have at last one engine. An engine is an object that knows what to do with an HTTP request. WiRL offers three engines: TWiRLEngine
is the basic engine that handles REST request, TWiRLFileSystemEngine
is capable of server static files and TWiRLhttpEngine
provides an OnExecute
event where the developer can handle the request. The most important Engine is, of course, the REST Engine: TWiRLEngine
while the others can be useful when you need to serve static files or to act like a "normal" HTTP server.
Applications
The WiRL engine can handle many sub-applications, each application can have different resources, filters and authentication systems but they can also be shared. Most of the configuration it's on the Application object.
Let's try with an example:
// First application
AServer
.CurrentEngine<TWiRLEngine>
.AddApplication('/auth')
.SetAppName('Autentication Module')
.SetResources([
'Server.Auth.TAuthResource,Server',
'Audit.TMonitorResource'])
;
// Second application
AServer
.CurrentEngine<TWiRLEngine>
.AddApplication('/order')
.SetAppName('Order Module')
.SetResources([
'Server.Order.TOrderResource',
'Server.Order.TCustomerResource',
'Server.Audit.TMonitorResource'])
;
end;
In this example we configure two applications, the first handles two resources: TAuthResource and TMonitorResource the second three resources: TOrderResource, TCustomerResource and TMonitorResource. As you can see the TMonitorResource is used by both applications.
Application's plugins
Additional configuration in an Application is manages through the concept of "plugins". A (configuration) plugin it's essentially an interface that provide configuration for an Application sub-module. Currently there are 3 sub-modules available.
Auth configuration plugin
The IWiRLConfigurationAuth
interface let's you configure the Auth values:
- SetAuthChallenge
- SetAuthChallengeHeader
- SetTokenType
- SetTokenLocation
- SetTokenCustomHeader
Let's see an example of such configuration:
// Auth configuration
.Plugin.Configure<IWiRLConfigurationAuth>
.SetTokenType(TAuthTokenType.JWT)
.SetTokenLocation(TAuthTokenLocation.Bearer);
For more detail see Authentication guide.
JWT configuration plugin
The IWiRLConfigurationJWT
interface let's you configure the JWT settings:
- SetClaimClass
- SetAlgorithm
- SetSecret
- SetSecret
- SetPublicKey
- SetPrivateKey
Let's see an example of such configuration:
// JWT configuration (App plugin configuration)
.Plugin.Configure<IWiRLConfigurationJWT>
.SetClaimClass(TServerClaims)
.SetAlgorithm(TJOSEAlgorithmId.HS256)
.SetSecret(TEncoding.UTF8.GetBytes(edtSecret.Text));
For more detail see Authentication guide.
JSON serializer (Neon) plugin
The IWiRLConfigurationNeon
interface let's you configure the Neon settings:
- SetMembers
- SetMemberCase
- SetMemberCustomCase
- SetVisibility
- SetIgnoreFieldPrefix
- SetUseUTCDate
- SetPrettyPrint
Let's see an example of such configuration:
// Neon configuration (App plugin configuration)
.Plugin.Configure<IWiRLConfigurationNeon>
.SetPrettyPrint(True)
.SetUseUTCDate(True)
.SetMemberCase(TNeonCase.SnakeCase);
For more detail see Neon plugin documentation.