# WiRL Attributes

One of WiRL's distinctive features is its ability to let developers write **ordinary classes** using standard native objects and types, and then "remotize" the methods of these classes. To understand how these methods should be used in the context of a REST call, WiRL relies on a series of Attributes that must be applied to the **class**, its **methods**, and **parameters**.
These attributes are found in the WiRL.Core.Attributes unit, and we'll analyze them in detail in the following sections.

![](../public/attributes.png){ width=100% }

::: warning
If you forget to add the unit with the definition of the attributes Delphi will generate a *Warning*: `W1074 Unknown custom attribute`. The program will still compile but will not work. **From Delph 10.3 you can transform the Warning into an error in the Delphi options or for a single project**.
:::

## Attributes for defining a RESTful resource

REST resources are the fundamental elements of any RESTful web service. A REST resource can be defined as an object that is of a specific type with the associated data and is optionally associated with other resources. It also exposes a set of standard operations corresponding to the HTTP method types.

::: info
Resource classes are Delphi PODO classes, which use WiRL annotations to implement a web service. Each resource class must have at least one method annotated with `[Path]` or a request method attribute `[HttpMethod]`.
:::

###### Attribute: `Path`

The `[Path]` attribute indicates the URI path to which a resource class or a class method must respond. The value that you specify for the [Path] attribute is relative to the URI of the server where the REST resource is hosted.

::: info
A `[Path]` attribute value is not required to have leading or trailing slashes (/), as you may see in some examples. The WiRL runtime will parse the URI path templates in the same way even if they have leading or trailing slashes.
:::

This attribute must be applied to a class, in that way WiRL will consider it a resource. It can applied to a method too, then the two paths will be combined together in a new sub-resource.

```pascal
  [Path('user')]
  TUserResource = class(TObject)
  public
    [GET]
    [Produces(TMediaType.APPLICATION_JSON)]
    function GetUser(...): ...;

    [GET]
    [Path('{id}/todo')]
    [Produces(TMediaType.APPLICATION_JSON)]
    function GetUserTodo(...): ...;
```

In this example the `/user` path will be accessible via the path GetUser method. In the second example the path contains a **template** `Path('{id}/todo')`. Templates are strings that contain variable parts (in this case id) that are accessible to the method via the attribute `PathParam` explained below. This method will then be accessible from URLs like `/user/12/todo` or `/user/lminuti/todo`.

However, the full URL of the resource will also depend on the configuration set to `TWiRLServer`, `TWiRLEngine` and `TWiRLApplication` as explained [here](/server/tutorial/getting-started).

![](../WiRLURL.png)


## Attributes for processing HTTP request methods

###### Attribute: `GET`

Applied to a class method. The method should be called only if the HTTP method is `GET`.

###### Attribute: `PUT`

Applied to a class method. The method should be called only if the HTTP method is `PUT`.

###### Attribute: `POST`

Applied to a class method. The method should be called only if the HTTP method is `POST`.

###### Attribute: `DELETE`

Applied to a class method. The method should be called only if the HTTP method is `DELETE`.

## Attributes for specifying content media types

###### Attribute: `Produces`

As we saw previously, WiRL associates the resource with the method of a class based on the attributes indicating the HTTP method and the path. However, the client can also indicate, via the [Accept](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept) header, the desired response format. The `Produces` attribute must indicate one or more formats in which the method is capable of returning the response.

> *Warning* : This attribute is used only to "match" between request and method. That WiRL will execute the method code which will presumably return something as output. It's only at the end of this process that WiRL, through the **MessageBodyWriters**, will attempt to convert the output into the required format. In the absence of an appropriate MessageBodyWriter WiRL will return the error `415 - MediaType [%s] not supported on resource [%s]`.

###### Attribute: `Consumes`

This attribute behaves similarly to `Produces` but with respect to a resource's input. With the *PUT* and *POST* methods, for example, a message is sent to the server. The format of the message is indicated by the [Content-Type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) header. In this case the header must match what is declared with the `Consumes` attribute. Once this has been done via the attribute `BodyParam` it will be possible to read the message sent by the client.

```pascal
  [Path('user')]
  TUserResource = class(TObject)
  public
    [POST]
    [Consumes(TMediaType.APPLICATION_JSON)]
    [Produces(TMediaType.APPLICATION_JSON)]
    function AppendUser([BodyParam] AUser: TUser): TUser;

  end;
```

In this example the method `AppendUser` expects a message in *JSON* format. If the message is indeed in this format WiRL will look for a **MessageBodyReader** capable of transforming a *JSON* into *TUser*. If it doesn't find it it will return the error `Unsupported media type [%s] for param [%s]`.

## Attributes for accessing request parameters

###### Attribute: `PathParam`

If a URL has been defined via the attribute `Path` containing a *template*, the content of the template will be associated with the parameter decorated with the attribute `PathParam`.

```pascal
  [Path('user')]
  TUserResource = class(TObject)
  public
    [GET]
    [Produces(TMediaType.APPLICATION_JSON)]
    function GetAllUsers(): TObjectList<TUser>;

    [GET]
    [Path('{id}')]
    [Produces(TMediaType.APPLICATION_JSON)]
    function GetUserById([PathParam('id')] AId: Integer): TUser;

    [GET]
    [Path('{id}/todo/{category}')]
    [Produces(TMediaType.APPLICATION_JSON)]
    function GetUserTodo(
        [PathParam('id')] AId: Integer
        [PathParam('category')] const ACategory: string
    ): TObjectList<TTodo>;
```

Let's consider several URLs:

* `/user`: This path will cause the method to be called `GetAllUsers`
* `/user/12`: In this case the method will be called `GetUserById` and the value *12*, which is part of the template, will be passed to the parameter `AId`. In fact, the name of the template parameter `Id` matches the value of the attribute `PathParam`.
* `/user/12/todo/done`: in this case the `GetUserTodo` method will be called and the parameters `AId` and `ACategory` receive 12 and the *done* string.

###### Attribute: `QueryParam`

QueryParam allows you to capture parameters passed via [query string](https://en.wikipedia.org/wiki/Query_string).

```pascal
  [Path('user')]
  TUserResource = class(TObject)
  public    
    [GET]
    [Produces(TMediaType.APPLICATION_JSON)]
    function GetUser(
        [QueryParam('name')] const AName: string;
        [QueryParam('email')] const AEmail: string
    ): TObjectList<TUser>;
```

In this example with a URL like:

`/user?name=lminuti&email=lminuti@examples.com`

WiRL will set the parameters `AName` and `AEmail` with the appropriate values.

###### Attribute: `FormParam`

This attribute works similarly to `QueryParam` but searches for parameters in the message body. *WiRL*, in this case, expects the body of the message to be in the `application/x-www-form-urlencoded` format, then decodes it and passes the values to the method parameters.

###### Attribute: `BodyParam`

This attribute allows you to read the entire body of the message as long as the format used is compatible with that indicated in the `Consumes` attribute and there is some **MessageBodyReader** capable of transforming the message into the indicated object.

```pascal
  [Path('user')]
  TUserResource = class(TObject)
  public
    [POST]
    [Consumes(TMediaType.APPLICATION_JSON)]
    [Produces(TMediaType.APPLICATION_JSON)]
    function AppendUser([BodyParam] AUser: TUser): TUser;

  end;
```

In this example the `AppendUser` method expects a message in *JSON* format. If this is true WiRL will look for a **MessageBodyReader** capable of transforming a *JSON* into *TUser*.

###### Attribute: `HeaderParam`

Similar to `FormParam` or `QueryParam` but looks for the data in a header that must be specified in the attribute.

###### Attribute: `CookieParam`

Similar to the previous one but looks for the data in a cookie.

###### Attribute: `MultiPart`

This attribute allows reading parameters passed through a `multipart/form-data` POST request. In this case, the individual values sent can be read directly or via the `TWiRLFormDataPart` class. Let's look at an example:

```pascal
    [POST]
    [Path('/multipart')] 
    [Consumes(TMediaType.MULTIPART_FORM_DATA)]
    [Produces(TMediaType.APPLICATION_JSON)]
    function PostMultiPartExample(
      [FormParam] AValue: string;
      [FormParam] AContent: TWiRLFormDataPart;
      [FormParam] AJSON: TJSONObject
    ): TJSONObject;
  end;
```

In this case, the resource expects to find three parameters: `AValue`, `AContent`, and `AJSON`. The first and last are read directly, while the second uses `TWiRLFormDataPart`. The advantage of this class is that it allows you to obtain additional information about the parameter. In fact, each part of a multipart message contains special attributes (name, format, compression type, etc.).

###### Attribute: `DefaultValue`

This attribute allows assigning a value to a parameter in case it is not provided by the client.

###### Attribute: `Context`

The *Context* attribute is used to obtain special context information as explained here: [Context Injection](context-injection). It can be applied to either a class variable or a method parameter.

## Attributes to specify access-control the REST methods

###### Attribute: `PermitAll`

This attribute (on a method) indicates that the method can be used by anyone as long as they are authenticated.

###### Attribute: `DenyAll`

*DenyAll* blocks a method for any user.

###### Attribute: `RolesAllowed`

This attribute (on a method) allows you to specify one or more roles that will have permission to use the method.

## Attributes to specify the lifespan of returned entities 

###### Attribute: `Singleton`

The *Singleton* attribute applies to either a method or the definition of a class. It indicates whether all instances of the class, or only the one returned by the method it is applied to, should be destroyed at the end of the HTTP call. For more information, see the chapter [Memory management](memory-management).

## Attributes to specify Filters properties

###### Attribute: `PreMatching`

Used to indicate that a filter should be invoked even if the resource, application, or engine does not exist (see [Filters](filters)).

###### Attribute: `PreMatchingResource`

Used to indicate that a filter should be invoked even if the resource does not exist (see [Filters](filters)).

###### Attribute: `NameBinding`

Applied to a custom attribute to create a "bind" between filters and resources (see [Filters](filters)).

###### Attribute: `Priority`

Indicates the priority of a filter (see [Filters](filters)).
# Authentication and Authorization

WiRL offers a robust and flexible system for handling both authentication and authorization in your API. While it's possible to create custom authentication processes using *filters* and *context injection* (see example *12.Context*), WiRL also provides several classes that significantly simplify the developer's work.

## Understanding Authentication vs. Authorization

Before diving into the implementation details, it's essential to understand the difference between these two concepts:

- **Authentication**: The process of verifying the identity of a user.
- **Authorization**: Determining what actions or resources an authenticated user is allowed to access.

WiRL allows you to manage both aspects seamlessly.

## Configuring Authentication

The `IWiRLConfigurationAuth` interface allows you to set up the basic authentication parameters for your application. Here's an example of a simple configuration:

```pascal
.Plugin.Configure<IWiRLConfigurationAuth>
  .SetTokenType(TAuthTokenType.JWT)
  .SetTokenLocation(TAuthTokenLocation.Bearer)
  .BackToApp
```

This configuration sets up [JWT](https://jwt.io/) authentication with the token being passed with a *Bearer* authentication.  The client must send this token in the Authorization header when making requests to protected resources:

```http
Authorization: Bearer <token>
```

However, `IWiRLConfigurationAuth` offers more options for fine-tuning your authentication. Each parameter is set using a corresponding `Set<ParameterName>` function. Here are the key parameters:

### AuthChallenge

The `SetAuthChallenge` method allows you to specify the type of challenge (Basic, Digest, Bearer, or Form) and the authentication realm when the access is denied.

### AuthChallengeHeader

Sets the name of the header where the challenge will be inserted. Default is 'WWW-Authenticate'.

### TokenType

Specifies the type of token to be used. Currently, only JWT is supported.

### TokenLocation

Defines where WiRL should look for the authentication token. Options: Bearer (in Authorization header), Cookie, Header (custom header).

### TokenCustom

When `SetTokenLocation` is set to Header, this specifies the name of the custom header.

## Authentication Process Overview

The authentication process in WiRL primarily consists of two phases:

1. User recognition
2. Role assignment

While WiRL allows you to define these phases manually, it also offers streamlined solutions for common scenarios, such as username/password authentication and JWT (JSON Web Token) role management.

## Standard Authentication Resources

WiRL provides several high-level classes that handle most of the work for standard authentication schemes. Let's explore these options:

### 1. TWiRLAuthBasicResource

Use this class when your authentication is based on [Basic Authentication](https://en.wikipedia.org/wiki/Basic_access_authentication). 

![](jwt.png){class=center-25 width=100%}

Here's how to implement it:

```pascal
[Path('basic_auth')]
TBasicAuthResource = class(TWiRLAuthBasicResource)
private
  // Injects the custom claims into "Subject" field
  [Context] Subject: TServerClaims;
protected
  function Authenticate(const AUserName, APassword: string): TWiRLAuthResult; override;
end;
```

In this example, `Subject` represents the JWT token. It can be of type `TWiRLSubject` or a derived class if you need custom attributes.

Here's an example implementation of the `Authenticate` method:

```pascal
function TFormAuthResource.Authenticate(const AUserName, APassword: string): TWiRLAuthResult;
begin
  // Replace this with your actual server authentication logic
  Result.Success := SameText(APassword, 'mypassword');
  
  // Assign roles based on the username (replace with your actual role assignment logic)
  if SameText(AUserName, 'admin') or SameText(AUserName, 'paolo') then
    Result.Roles := 'user,manager,admin'.Split([','])
  else
    Result.Roles := 'user,manager'.Split([',']);
  
  // Set JWT claims
  Subject.Expiration := IncSecond(Now(), 30);
  Subject.UserID := AUserName;
  
  // Set custom JWT claims
  Subject.Language := 'it-IT';
end;
```

This method verifies the username and password, sets the appropriate roles, and configures the JWT claims.

### 2. TWiRLAuthFormResource

This class is similar to `TWiRLAuthBasicResource`, but it retrieves the username and password from the HTTP request body, assuming they're in `www-form-urlencoded` format. The `Authenticate` method implementation is similar to the previous example.

### 3. TBodyAuthResource

This class follows the same principle but expects the username and password to be sent in the request body as JSON.

## Advanced Authentication Scenarios

This chapter covers advanced authentication scenarios, focusing on customizing JWT tokens and authentication responses. These techniques allow you to extend the default behavior of WiRL's authentication mechanisms to better suit your application's needs.

### Customizing JWT Tokens

By default, WiRL provides a standard JWT token structure, but you might need to include additional custom claims in your tokens. This section demonstrates how to customize the JWT token by creating a custom subject class.

### Creating a Custom Subject Class

To customize the JWT token, you need to create a class that inherits from `TWiRLSubject`. This class will define additional claims you want to include in your token.

```delphi
TMyServerClaims = class(TWiRLSubject)
private
  const CLAIM_GROUP = 'group';
  const CLAIM_LANGUAGE = 'language';
private
  function GetGroup: string;
  function GetLanguage: string;
  procedure SetLanguage(const Value: string);
  procedure SetGroup(const Value: string);
public
  property Group: string read GetGroup write SetGroup;
  property Language: string read GetLanguage write SetLanguage;
end;
```

The implementation of the getter and setter methods map directly to specific sections in the JWT JSON payload:

```delphi
function TMyServerClaims.GetGroup: string;
begin
  Result := TJSONUtils.GetJSONValue(CLAIM_GROUP, FJSON).AsString;
end;

function TMyServerClaims.GetLanguage: string;
begin
  Result := TJSONUtils.GetJSONValue(CLAIM_LANGUAGE, FJSON).AsString;
end;

procedure TMyServerClaims.SetGroup(const Value: string);
begin
  if Value = '' then
    TJSONUtils.RemoveJSONNode(CLAIM_GROUP, FJSON)
  else
    TJSONUtils.SetJSONValueFrom<string>(CLAIM_GROUP, Value, FJSON);
end;

procedure TMyServerClaims.SetLanguage(const Value: string);
begin
  if Value = '' then
    TJSONUtils.RemoveJSONNode(CLAIM_LANGUAGE, FJSON)
  else
    TJSONUtils.SetJSONValueFrom<string>(CLAIM_LANGUAGE, Value, FJSON);
end;
```

This pattern is commonly used when creating custom JWT subjects: each property maps to a specific section of the JSON payload in the JWT token. Remember that JWT tokens are essentially JSON objects that are encoded and signed.

### Configuring WiRL to Use the Custom Subject Class

After defining your custom subject class, you need to configure WiRL to use it during the authentication process:

```delphi
.Plugin.Configure<IWiRLConfigurationJWT>
  .SetClaimClass(TMyServerClaims)
  .SetAlgorithm(TJOSEAlgorithmId.HS256)
  .SetSecret(TEncoding.UTF8.GetBytes(MySecret))
```

This configuration tells WiRL to:
1. Use your custom `TMyServerClaims` class for JWT claims
2. Use the HS256 algorithm for token signing
3. Set the secret key for token signing

### Customizing Authentication Responses

By default, WiRL returns a simple JSON response with `success` and `access_token` fields. You can customize this response by extending the `TWiRLLoginResponse` class:

```delphi
TMyCustomLoginResult = class(TWiRLLoginResponse)
private
  FLanguage: string;
  FUserID: string;
  FCustomInfo: string;
public
  property Language: string read FLanguage write FLanguage;
  property UserID: string read FUserID write FUserID;
  property CustomInfo: string read FCustomInfo write FCustomInfo;
end;
```

This custom class adds three additional fields to the authentication response:

- `Language`: The user's preferred language
- `UserID`: The identifier for the authenticated user
- `CustomInfo`: Any additional custom information you want to include

Remember that this class will be serialized using *Neon*. Therefore, you can apply any Neon attributes to customize the JSON output (such as [NeonProperty], [NeonIgnore], etc.).

### Putting It All Together

Here's how you can implement a custom authentication resource that uses both the custom JWT subject and the custom response:

```delphi
[Path('basic_auth')]
TBasicAuthResource = class(TWiRLAuthBasicResource)
private
  // Injects the custom claims into "Subject" field
  [Context] Subject: TServerClaims;
protected
  function Authenticate(const AUserName, APassword: string): TWiRLAuthResult; override;
  function CreateResponse(ASuccess: Boolean; const AToken: string): TWiRLLoginResponse; override;
end;
```

The `Authenticate` method remains the same as in previous examples, while the `CreateResponse` method is overridden to return your custom response:

```delphi
function TBasicAuthResource.CreateResponse(ASuccess: Boolean;
  const AToken: string): TWiRLLoginResponse;
var
  LCustomAuthResult: TMyCustomLoginResult;
begin
  LCustomAuthResult := TMyCustomLoginResult.Create(ASuccess, AToken);
  LCustomAuthResult.Language := Subject.Language;
  LCustomAuthResult.UserID := Subject.UserID;
  LCustomAuthResult.CustomInfo := 'custom_value';
  Result := LCustomAuthResult;
end;
```

This method:

1. Creates a new instance of your custom response class
2. Sets the success status and token (handled by the parent constructor)
3. Populates the additional fields with values from the Subject context and any other required values
4. Returns the custom response

## JWT Configuration

For applications using JWT, the `IWiRLConfigurationJWT` interface provides additional configuration options. Here's a basic example:

```pascal
.Plugin.Configure<IWiRLConfigurationJWT>
  .SetClaimClass(TServerClaims)
  .SetAlgorithm(TJOSEAlgorithmId.HS256)
  .SetSecret(TEncoding.UTF8.GetBytes(MySecretKey))
```

This sets up JWT with a custom claims class, using the HS256 algorithm and a specified secret key. Let's explore the available configuration methods:

### VerificationMode

Determines how the token should be processed. Options: `Verify` (default): Fully validate the token; `Deserialize`: Only deserialize the token without validation.

### ClaimClass

Specifies a custom class for JWT claims. Must be derived from `TWiRLSubject`. Default: `TWiRLSubject`.

### Algorithm

Sets the algorithm for generating and verifying JWT tokens. Options include HS256, HS384, HS512, RS256, RS384, RS512, ES256, ES384, ES512, PS256, PS384, PS512.

### Secret
For HMAC-based algorithms (HS256, HS384, HS512). Directly set the secret key as bytes or provide a function to generate it.

### PublicKey

For RSA-based algorithms. Sets the public key for token verification.

### PrivateKey

For RSA-based algorithms. Sets the private key for token signing.


## Introduction to WiRL Authorization

WiRL uses a decorator-style approach to define authorization rules. You can apply these decorators at the method level to control access to specific endpoints. Let's look at an example to see how this works in practice:

```pascal
[Path('user')]
TUserResource = class
protected
  // Injects the auth context into the "Auth" object
  [Context] Auth: TWiRLAuthContext;
  // Injects the custom claims into "Subject" object
  [Context] Subject: TServerClaims;
public
  [GET]
  [Produces(TMediaType.APPLICATION_JSON)]
  function PublicInfo: TUserInfo;

  [POST, RolesAllowed('admin,manager')]
  [Produces(TMediaType.APPLICATION_JSON)]
  function InsertUser([BodyParam] AUser: TUserInfo): TUserInfo;

  [GET, Path('/details'), RolesAllowed('admin')]
  [Produces(TMediaType.APPLICATION_JSON)]
  function DetailsInfo: TDetailsInfo;
end;
```

In this example, we define a `TUserResource` class with three methods, each with different authorization levels:

1. `PublicInfo`: This method has no authorization attributes, making it publicly accessible.
2. `InsertUser`: This method is decorated with `[RolesAllowed('admin,manager')]`, restricting access to users with either the 'admin' or 'manager' role.
3. `DetailsInfo`: This method is decorated with `[RolesAllowed('admin')]`, allowing access only to users with the 'admin' role.

## Available Authorization Attributes

WiRL provides three main attributes for controlling access to your resources:

1. `PermitAll`: This attribute allows access to the decorated method for any authenticated user. It's useful for endpoints that require authentication but don't need role-based restrictions.

2. `DenyAll`: This attribute blocks access to the decorated method for all users, regardless of their authentication status or roles. It's helpful when you want to temporarily disable an endpoint or restrict it entirely.

3. `RolesAllowed`: This attribute allows you to specify one or more roles that are permitted to access the decorated method. You can provide multiple roles as a comma-separated list, as seen in the `InsertUser` method above.

> **ATTENTION**: When a JWT token is sent in a request, WiRL only checks its validity (HMAC or RSA). After that, it verifies if the resource has the aforementioned attributes. It's crucial to remember that WiRL does not verify any claims in the token, not even the expiration. Therefore, if additional checks are necessary, it is recommended to use a [filter](/server/filters). Keep in mind that in filters, you can use [context injection](/server/context-injection), for example, to inject the JWT token for further processing.

## Accessing Authentication Context and Claims

WiRL can [inject](context-injection) authentication-related objects directly into your resource class, giving you access to important information about the current request's authentication status and the authenticated user's claims.

In the example above, we see two protected fields decorated with the `[Context]` attribute:

```pascal
[Context] Auth: TWiRLAuthContext;
[Context] Subject: TServerClaims;
```

1. `Auth: TWiRLAuthContext`: This object contains information about the authentication state of the current request, including details about token validity, token type, and other authentication-related metadata.

2. `Subject: TServerClaims`: This object represents the deserialized token, containing the actual claims of the authenticated user. In this example, we're using a custom `TServerClaims` type, which must be derived from `TWiRLSubject`.

By injecting these objects, you can easily access authentication and user information within your resource methods. This allows you to implement more complex authorization logic beyond simple role-based access control if needed.


# Writing your first resource

Developing a REST server with **WiRL** consists of creating a some classes linked to the resources of your API. Generally, a REST resource corresponds to a class and each HTTP method (GET, POST, PUT, DELETE, etc.) matches to a method of the class. Things can be more complicated if a resource, with the same HTTP method, provides multiple responses (for example with different format: JSON, XML, etc.); or in the case of *sub-resources* (e.g. for customer's invoices: customer resource, invoice sub-resource).

## Definition of the resource

Suppose we want to create a REST API that exposes a resource `user`. We also want our resource to be accessible for both reading and writing. Then we should create the following *endpoints*:

```
# Read the user by its ID
GET /api/user/{id}

# Get the users that match some conditions
GET /api/user?name={name}&email={email}

# Change a user (user data will be in a JSON inside the body request)
PUT /api/user/{id}

# Add a user
POST /api/user

# Delete a user
DELETE /api/user/{id}
```

## Create the class

Now, if we are supposed to create a Delphi class that handles the resource, with a method for each `endpoint`, the most natural way to write it could be the following:

```pascal
  TUserResource = class(TObject)
  public
    // GET /api/user/{id}
    function GetUserById(AId: Integer): TUser;

    // GET /api/user?name={name}&email={email}
    function GetUser(const AName, AEmail: string): TObjectList<TUser>;

    // PUT /api/user/{id}
    function UpdateUser(AId: Integer; AUser: TUser): TUser;

    // POST /api/user
    function AppendUser(AUser: TUser): TUser;

    // DELETE /api/user/{id}
    function DeleteUser(AId: Integer): TUser;

  end;
```

What WiRL allows you to do is just take that class, as is, and make it accessible via *HTTP*. Obviously there are some things WiRL needs to know before making API publishing possible. Some are related to the general [configuration](configuration) of the application (the port, the message format, etc.), and then there are some information related to the resource itself.

As you can see, we have inserted some comments in the class needed to understand how the class methods are associated with HTTP methods. This information must be accessible to *WiRL*, what we need to do is transform the comments into a series of [attributes](attributes) made available by the library:

```pascal
  [Path('user')]
  TUserResource = class(TObject)
  public
    [GET]
    [Path('{id}')]
    [Produces(TMediaType.APPLICATION_JSON)]
    function GetUserById([PathParam('id')] AId: Integer): TUser;

    [GET]
    [Produces(TMediaType.APPLICATION_JSON)]
    function GetUser(
        [QueryParam('name')] const AName: string;
        [QueryParam('email')] const AEmail: string
    ): TObjectList<TUser>;

    [PUT]
    [Path('{id}')]
    [Consumes(TMediaType.APPLICATION_JSON)]
    [Produces(TMediaType.APPLICATION_JSON)]
    function UpdateUser(
        [PathParam('id')] AId: Integer; 
        [BodyParam] AUser: TUser
    ): TUser;

    [POST]
    [Consumes(TMediaType.APPLICATION_JSON)]
    [Produces(TMediaType.APPLICATION_JSON)]
    function AppendUser([BodyParam] AUser: TUser): TUser;

    [DELETE]
    [Path('{id}')]
    [Produces(TMediaType.APPLICATION_JSON)]
    function DeleteUser([PathParam('id')] AId: Integer): TUser;

  end;
```

In this way *WiRL* has all the information it needs.

## The attributes

The `WiRL.Core.Attributes` unit has several attributes, here we will only see those relating to the definition of resources.

::: warning
If you forget to add the unit with the definition of the attributes Delphi will generate a *Warning*: `W1074 Unknown custom attribute`. The program will still compile but will not work. **From Delph 10.3 you can transform the Warning into an error in the Delphi options or for a single project**.
:::

**Attribute**: `Path`

This attribute must be applied to a class, in that way WiRL will consider it a resource. It can applied to a method too, then the two paths will be combined together in a new sub-resource.

```pascal
  [Path('user')]
  TUserResource = class(TObject)
  public
    [GET]
    [Produces(TMediaType.APPLICATION_JSON)]
    function GetUser(...): ...;

    [GET]
    [Path('{id}/todo')]
    [Produces(TMediaType.APPLICATION_JSON)]
    function GetUserTodo(...): ...;
```

In this example the `/user` path will be accessible via the path GetUser method. In the second example the path contains a **template** `Path('{id}/todo')`. Templates are strings that contain variable parts (in this case id) that are accessible to the method via the attribute `PathParam` explained below. This method will then be accessible from URLs like `/user/12/todo` or `/user/lminuti/todo`.

However, the full URL of the resource will also depend on the configuration set to `TWiRLServer`, `TWiRLEngine` and `TWiRLApplication` as explained [here](/server/tutorial/getting-started).

![](../WiRLURL.png)


**Attribute**: `GET`

Applied to a class method. The method should be called only if the HTTP method is `GET`.

**Attribute**: `PUT`

Applied to a class method. The method should be called only if the HTTP method is `PUT`.

**Attribute**: `POST`

Applied to a class method. The method should be called only if the HTTP method is `POST`.

**Attribute**: `DELETE`

Applied to a class method. The method should be called only if the HTTP method is `DELETE`.

**Attribute**: `Produces`

As we saw previously, WiRL associates the resource with the method of a class based on the attributes indicating the HTTP method and the path. However, the client can also indicate, via the [Accept](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept) header, the desired response format. The `Produces` attribute must indicate one or more formats in which the method is capable of returning the response.

> *Warning* : This attribute is used only to "match" between request and method. That WiRL will execute the method code which will presumably return something as output. It's only at the end of this process that WiRL, through the **message body writers**, will attempt to convert the output into the required format. In the absence of an appropriate message body writer WiRL will return the error `415 - MediaType [%s] not supported on resource [%s]`.

**Attribute**: `Consumes`

This attribute behaves similarly to `Produces` but with respect to a resource's input. With the *PUT* and *POST* methods, for example, a message is sent to the server. The format of the message is indicated by the [Content-Type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) header. In this case the header must match what is declared with the `Consumes` attribute. Once this has been done via the attribute `BodyParam` it will be possible to read the message sent by the client.

```pascal
  [Path('user')]
  TUserResource = class(TObject)
  public
    [POST]
    [Consumes(TMediaType.APPLICATION_JSON)]
    [Produces(TMediaType.APPLICATION_JSON)]
    function AppendUser([BodyParam] AUser: TUser): TUser;

  end;
```

In this example the method `AppendUser` expects a message in *JSON* format. If the message is indeed in this format WiRL will look for a **message body reader** capable of transforming a *JSON* into *TUser*. If it doesn't find it it will return the error `Unsupported media type [%s] for param [%s]`.

**Attribute**: `PathParam`

If a URL has been defined via the attribute `Path` containing a *template*, the content of the template will be associated with the parameter decorated with the attribute `PathParam`.

```pascal
  [Path('user')]
  TUserResource = class(TObject)
  public
    [GET]
    [Produces(TMediaType.APPLICATION_JSON)]
    function GetAllUsers(): TObjectList<TUser>;

    [GET]
    [Path('{id}')]
    [Produces(TMediaType.APPLICATION_JSON)]
    function GetUserById([PathParam('id')] AId: Integer): TUser;

    [GET]
    [Path('{id}/todo/{category}')]
    [Produces(TMediaType.APPLICATION_JSON)]
    function GetUserTodo(
        [PathParam('id')] AId: Integer
        [PathParam('category')] const ACategory: string
    ): TObjectList<TTodo>;
```

Let's consider several URLs:

* `/user`: This path will cause the method to be called `GetAllUsers`
* `/user/12`: In this case the method will be called `GetUserById` and the value *12*, which is part of the template, will be passed to the parameter `AId`. In fact, the name of the template parameter `Id` matches the value of the attribute `PathParam`.
* `/user/12/todo/done`: in this case the `GetUserTodo` method will be called and the parameters `AId` and `ACategory` receive 12 and the *done* string.

**Attribute**: `QueryParam`

QueryParam allows you to capture parameters passed via [query string](https://en.wikipedia.org/wiki/Query_string).

```pascal
  [Path('user')]
  TUserResource = class(TObject)
  public    
    [GET]
    [Produces(TMediaType.APPLICATION_JSON)]
    function GetUser(
        [QueryParam('name')] const AName: string;
        [QueryParam('email')] const AEmail: string
    ): TObjectList<TUser>;
```

In this example with a URL like: `/user?name=lminuti&email=lminuti@examples.com` WiRL will set the parameters `AName` and `AEmail` with the appropriate values.

**Attribute**: `FormParam`

This attribute works similarly to `QueryParam` but searches for parameters in the message body. *WiRL*, in this case, expects the body of the message to be in the `application/x-www-form-urlencoded` format, then decodes it and passes the values to the method parameters.

**Attribute**: `BodyParam`

This attribute allows you to read the entire body of the message as long as the format used is compatible with that indicated in the `Consumes` attribute and there is someone **message body reader** capable of transforming the message into the indicated object.

```pascal
  [Path('user')]
  TUserResource = class(TObject)
  public
    [POST]
    [Consumes(TMediaType.APPLICATION_JSON)]
    [Produces(TMediaType.APPLICATION_JSON)]
    function AppendUser([BodyParam] AUser: TUser): TUser;
  end;
```

In this example the `AppendUser` method expects a message in *JSON* format. If this is true WiRL will look for a **message body reader** capable of transforming a *JSON* into *TUser*.

**Other attributes**

There are other attributes that, similarly to what we saw previously, are responsible for reading: *header*, *cookie*, [JWT token](https://jwt.io/) and more. See also [Attributes](attributes).

## Conversion of parameters

In general, when *WiRL* associates a value read from the HTTP request to a method parameter, it will try to convert it in the right way. You can customize the way WiRL performs this type of conversion (e.g. the date format or decimal separator) via `IWiRLFormatSetting`.

```pascal
  FServer.AddEngine<TWiRLEngine>('/rest')
    .SetEngineName('RESTEngine')
    .AddApplication('/app')
      .SetResources('*')
      .SetFilters('*')

      .Plugin.Configure<IWiRLFormatSetting>
        .AddFormat(TypeInfo(TDateTime), TWiRLFormatSetting.ISODATE_UTC)
        .BackToApp
    // ...
```

Furthermore, if a method parameter is a class with a constructor that takes as input a single string parameter, *WiRL* will automatically instantiate the object, passing the read parameter to the constructor.

```pascal
  TUserIdList = class
  public
    constructor Create(const AList: string);
  end;

  [Path('user')]
  TUserResource = class(TObject)
  public    
    [GET]
    [Produces(TMediaType.APPLICATION_JSON)]
    function GetUsers(
        [QueryParam('id')] AIdList: TUserIdList
    ): TObjectList<TUser>;
```

With a request like:

```
GET /user?id=1,2,3,4
```

The object will be instantiated by passing the string `1,2,3,4` to the constructor parameter.

## Registration

Finally we need to register the class that implements the resource inside the **resource registry**. This is usually done in the *initialization* section of the *unit* where the class is defined.

For the `TUserResource` class we need the following code:

```pascal
initialization
   TWiRLResourceRegistry.Instance.RegisterResource<TUserResource>;
```

Now, when *WiRL* needs the `TUserResource` is able to create an instance using a parameterless constructor. If the class does not have a parameterless constructor, we have to provide an anonymous method that can instantiate the object:

```pascal
   TWiRLResourceRegistry.Instance.RegisterResource<TUserResource>(
     function: TObject
     begin
       Result := TUserResource.Create(...);
     end
   );
```# WiRL 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](https://en.wikipedia.org/wiki/Fluent_interface). 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:

```pascal [fluent]
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;

```

```pascal [classic]
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:

> htt<span>p://l</span>ocalhost: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:

```pascal
  // 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:

```pascal
  // 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:

```pascal
  // Auth configuration
  .Plugin.Configure<IWiRLConfigurationAuth>
    .SetTokenType(TAuthTokenType.JWT)
    .SetTokenLocation(TAuthTokenLocation.Bearer);
```

For more detail see [Authentication](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:

```pascal
  // JWT configuration (App plugin configuration)
  .Plugin.Configure<IWiRLConfigurationJWT>
    .SetClaimClass(TServerClaims)
    .SetAlgorithm(TJOSEAlgorithmId.HS256)
    .SetSecret(TEncoding.UTF8.GetBytes(edtSecret.Text));
```

For more detail see [Authentication](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:

```pascal
  // Neon configuration (App plugin configuration)
  .Plugin.Configure<IWiRLConfigurationNeon>
    .SetPrettyPrint(True)
    .SetUseUTCDate(True)
    .SetMemberCase(TNeonCase.SnakeCase);

```

For more detail see [Neon plugin](neon) documentation.# Context Injection

One of the main features of WiRL is that you can use any class to build your resources, with no need to inherit from a specific class. This design philosophy encourages a clean separation between your business logic and the REST infrastructure that exposes it. When developing with WiRL, you typically write your classes without concerning yourself with the underlying REST mechanisms, allowing you to focus on your domain model and business rules.
This separation is achieved through attributes like `[PathParam]`, `[QueryParam]`, `[BodyParam]`, and `[HeaderParam]`, which serve as bridges between your domain classes and the HTTP protocol. These attributes instruct WiRL on how to map REST concepts to your methods and their parameters, effectively shielding your code from the lower-level details of HTTP requests, responses, and headers.
However, there are situations where you might need direct access to the underlying connection data or WiRL's internal state. These could include cases where WiRL lacks a specific feature you need, or when you have unique requirements that demand finer control over the HTTP communication. This is where context injection becomes valuable.
Context injection allows you to request specific objects from WiRL that provide access to lower-level components such as the HTTP request, HTTP response, or even WiRL's internal structures like `TWiRLApplication` and `TWiRLServer`. As with other aspects of WiRL, you communicate these requirements through attributes.
It's important to emphasize that while context injection provides powerful capabilities, it should be considered an exception rather than the rule. Direct interaction with these lower-level components breaks the clean separation between your business logic and the REST infrastructure, potentially making your code more tightly coupled to WiRL and HTTP concepts. Therefore, this approach should be reserved for specific scenarios where the standard attribute-based mappings are insufficient.
The following sections will explore the various contexts that can be injected and how to use them effectively while maintaining code quality.

## Available Context Objects

WiRL provides several context objects that can be injected into your **resources**, **filters**, message body **readers**, and message body **writers**. Each of these objects offers specific functionality and access to different aspects of the WiRL framework and the HTTP communication process. 

### TWiRLServer

The WiRL server instance that handles incoming HTTP requests. This object can be useful for:

* Checking server status (active or inactive)
* Obtaining the port number the server is running on
* Accessing the underlying connection implementation object (by default, a `TIdHttpServer` instance)

### TWiRLEngine

The WiRL engine that manages applications and dispatches requests. You might use this to access:

* The engine type (typically TWiRLRESTEngine)
* Path and name information
* Global engine configuration

### TWiRLApplication

The current WiRL application instance handling the request. This provides access to:

* Application name
* Configuration settings
* Managed objects such as filters, resources, readers, and writers

**Important Note**: Write operations on `TWiRLServer`, `TWiRLEngine`, and `TWiRLApplication` are not thread-safe and can be dangerous in a multi-threaded server environment. Use caution when modifying these objects.

### TWiRLRequest

Contains all data related to the current HTTP request. This object is modifiable, allowing filters to potentially alter the request before it reaches a resource. This can be used to:

* Access request headers, body content, and other HTTP details
* Modify request parameters to force specific behavior in resources
* Implement custom authentication or request validation logic

### TWiRLResponse

Represents the HTTP response that will be sent back to the client. When injected into a filter that executes after a resource, it will already contain the response generated by the resource. This allows filters to:

* Modify response content, headers, or status code
* Apply compression algorithms
* Implement encryption
* Add custom headers or metadata

### TWiRLURL

A utility object that helps parse and interpret the individual parts of a URL. Useful for:

* Analyzing URL components
* Building or modifying URLs programmatically
* Extracting specific segments from complex paths

### TWiRLAuthContext

Used for working with **JWT** (JSON Web Token) authentication. This object provides methods to:

* Generate new JWT tokens
* Verify token validity
* Delete tokens
* Read token information

### TWiRLSubject

Contains all claims data from the JWT token associated with the current request. This provides:

* User identity information
* Custom claim values
* Role and permission details (if included in the token)
* Token metadata

## Inject standard objects

The following example shows how to inject the request and the response to a resource, in this case the attribute is `[Context]`.

```pascal
type
  [Path('/myresource')]
  TMyResource = class
  private
    [Context] Application: TWiRLApplication;
  public
    [GET]
    [Produces(TMediaType.APPLICATION_JSON)]
    function List([Context] Request: TWiRLRequest; [Context] Response: TWiRLResponse): string;
  end;
```

The `[Context]` attribute can be used to decorate instance variables, properties and method parameters. WiRL provides to inject the correct object to your variables before the resource method is invoked. WiRL matches the right object by its class. 

## Custom injection

### Creating Your Own Injectable Components

WiRL's context injection system is not limited to the built-in framework objects. If you have custom classes that you need to use across multiple components in your application, you can create your own context injection factories to make these objects available throughout your REST application.
Custom context objects, like the built-in ones, can be injected into resources, filters, message body readers, and message body writers. This provides a consistent way to access your application-specific objects wherever they're needed in the request processing pipeline.
Some examples of custom objects you might want to inject include:

* Application configuration managers
* Business logic components or data modules
* Custom HTTP header parsers
* Database connection managers
* Logging services
* Authentication or authorization handlers

The HTTP header parser example is particularly valuable because it allows you to encapsulate the logic for interpreting specific headers once, then simply inject this functionality wherever it's needed. This promotes code reuse and keeps your resources focused on their primary responsibilities.

### Lifecycle Management

An important consideration when implementing custom context objects is their lifecycle. By default, objects created through a custom context factory are instantiated for each individual HTTP connection and destroyed when that connection terminates. This per-request lifecycle is appropriate for many use cases, particularly when the object needs to maintain state specific to the current request.
However, there are situations where you might want a longer-lived object:

1. When the object is stateless and can be safely shared across requests
2. When the object is expensive to create (like database connections)
3. When the object needs to maintain state across multiple requests

To extend the lifecycle of your custom context objects, you have two complementary approaches:

1. Decorate the injectable class with the `[Singleton]` attribute to indicate that it should not be destroyed at the end of each connection
2. Implement your factory to return the same instance for multiple requests instead of creating a new object each time

By combining these techniques, you can optimize resource usage while ensuring that your custom objects maintain the appropriate state for their intended purpose.
Remember that when using singleton objects in a multi-threaded server environment, you need to ensure they are thread-safe if they maintain any mutable state.

## Implementation example

Let's see a basic example:

```pascal
interface

type
  // Class to be injected
  TMyClass = class
  private
    FValue: Integer;
  public
    property Value: Integer read FValue write FValue;
  end;

  // The class factory is responsable to create the context.
  // It will be released by the system unless it's annotated
  // with the Singleton attribute
  TMyClassFactory = class(TInterfacedObject, IContextFactory)
  public
    function CreateContext(const AObject: TRttiObject;
      AContext: TWiRLContext): TValue;
  end;

implementation

function TMyClassFactory.CreateContext(const AObject: TRttiObject;
  AContext: TWiRLContext): TValue;
var
  LInstance: TMyClass;
begin
  LInstance := TMyClass.Create;
  LInstance.Value := 42;
  Result := LInstance;
end;

initialization
  TWiRLContextInjectionRegistry.Instance.RegisterFactory<TMyClass>(TMyClassFactory);
```

So you need to define your class, a factory that is capable of creating the class and register both classes. The interesting part is that in the `CreateContext` method of the factory you have a reference to `TWiRLContext`, so basically you have access to the HTTP request (and much more information) and you can create the class accordingly.# Cross-Origin Resource Sharing (CORS) in WiRL

Cross-Origin Resource Sharing (CORS) is a security mechanism that allows web servers to specify which origins (domains, schemes, or ports) are permitted to access their resources. This is particularly important in modern web applications where frontend and backend services may be hosted on different domains.

For a comprehensive understanding of CORS, please refer to the [MDN Web Docs on CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS).

## Implementing CORS in WiRL

WiRL provides a straightforward way to implement CORS in your REST applications through a configurable plugin. This plugin allows you to fine-tune your CORS settings to meet your specific security requirements.

### Basic Configuration

Here's an example of how to configure CORS in your WiRL application:

```pascal
RESTServer.AddEngine<TWiRLEngine>('/rest')
  .SetEngineName('RESTEngine')
  .AddApplication('/app')
    .SetResources('*')
    .SetFilters('*')
    // CORS plugin configuration
    .Plugin.Configure<IWiRLConfigurationCORS>
      .SetOrigin('*')
      .SetMethods('HEAD, GET, PUT, POST, DELETE, OPTIONS')
      .SetHeaders('Accept, Content-Type, Content-Encoding, Authorization')
```

### Configuration Parameters

The CORS plugin in WiRL can be customized using the `IWiRLConfigurationCORS` interface. Here are the key parameters you can set:

1. **Origin** (`SetOrigin`):
   - Specifies which origins are allowed to access your resources.
   - Use `'*'` to allow all origins.
   - Example for a specific origin: `SetOrigin('https://example.com')`

2. **Methods** (`SetMethods`):
   - Defines which HTTP methods are permitted from external origins.
   - Specify one or more of: HEAD, GET, PUT, POST, DELETE, OPTIONS.
   - Example: `SetMethods('GET, POST, PUT, DELETE')`

3. **Headers** (`SetHeaders`):
   - Indicates which HTTP headers are accepted in requests from external origins.
   - Example: `SetHeaders('Accept, Content-Type, Authorization')`

## Advanced CORS Handling

For more complex scenarios, such as differentiating responses based on the origin of the caller, WiRL allows you to use [custom filters](filters). This approach gives you fine-grained control over CORS responses.

## Troubleshooting

If you encounter CORS-related issues:

1. Check your browser's console for specific CORS error messages.
2. Ensure that your server is correctly sending the CORS headers.
3. Verify that the requesting origin matches the configured allowed origins.
4. For preflight requests (OPTIONS), make sure your server is handling them correctly.
# Deployment

In the previous chapters we have seen how to configure WiRL, how to write individual resources, filters and all other WiRL elements. But how can we create our application? First we will see some examples of the simplest methods, namely developing a VCL application or a console application. Both methods are useful especially during the debugging phase. Subsequently we will also see other deployment methods, in particular developing a Windows service, a Linux daemon and a console program optimized to run in a Docker container.

## Introduction

The common starting point for all application types is the WiRL server, and by this we mean the `TWiRLServer` class. This class is configured with various engines (REST, FileSystem, proxy, etc.) and when instantiated and started, it listens on the specified port and handles communication.

Furthermore, another point to keep in mind is that our application will probably have multiple operating modes, for example as a VCL Desktop app when we develop and as a Windows service when we deploy. To achieve this result we can act in various ways; the simplest is to create a project group where there are different projects that share most of the files (resources, filters, data model, etc.) but have different entry points. This method is what you can find in the `08.Platforms` example in the WiRL sources and which we will now analyze.

## The common parts

As already mentioned, most of the code (resources, filters, application logic, etc.) will need to be shared between the various versions of the application. The same applies to configuration; in this case it is essential to put the creation of the `TWiRLServer` object on a specific class. The solution is to create a new unit with a class (for example `TListener`) structured like this:

```pascal
unit Server.Listener;

interface

uses
  System.Classes, System.SysUtils,

  WiRL.Configuration.Core,
  WiRL.Core.Classes,
  WiRL.Engine.Core,
  WiRL.Engine.REST,
  WiRL.Core.Application,
  WiRL.Core.MessageBody.Default,
  WiRL.Data.MessageBody.Default,
  WiRL.http.Server,
  WiRL.http.Server.Indy;

type
  TListener = class(TObject)
  private
    FServer: TWiRLServer;
    FPort: Integer;
    FName: string;
    FDisplayName: string;
    function GetActive: Boolean;
    procedure SetPort(const Value: Integer);
  public
    property Name: string read FName;
    property DisplayName: string read FDisplayName;
    property Port: Integer read FPort write SetPort;

    procedure Start;
    procedure Stop;
    property Active: Boolean read GetActive;

    constructor Create;
    destructor Destroy; override;
  end;

implementation

uses
  WiRL.Core.JSON,
  WiRL.Rtti.Utils;


{ TListener }

constructor TListener.Create;
begin
  FPort := 8080;
  FName := 'WiRLDemo';
  FDisplayName := 'WIRL - Multiplatform demo';
end;

destructor TListener.Destroy;
begin
  Stop;
  inherited;
end;

function TListener.GetActive: Boolean;
begin
  Result := Assigned(FServer);
end;

procedure TListener.SetPort(const Value: Integer);
begin
  if Active then
    raise Exception.Create('Stop before change port');
  FPort := Value;
end;

procedure TListener.Start;
begin
  if Assigned(FServer) then
    Exit;

  FServer := TWiRLServer.Create(nil);

  // Server configuration
  FServer
    .SetPort(FPort)
    // Engine configuration
    .AddEngine<TWiRLRESTEngine>('/rest')
      .SetEngineName('WiRL Demo')

      // Application configuration
      .AddApplication('/app')
        .SetAppName('App')
        .SetFilters('*')
        .SetResources('*');

  if not FServer.Active then
    FServer.Active := True;
end;

procedure TListener.Stop;
begin
  if not Assigned(FServer) then
    Exit;

  FServer.Active := False;
  FreeAndNil(FServer);
end;

end.
```

Obviously the `TWiRLServer` configuration may change, but what we try to do with this class is define a series of methods and properties that are suitable for each development mode (VCL Application, Windows service, etc.). Let's look at the characteristics of this class one by one:

* `property Name`: will be used for example as a name to register the Windows Service.
* `property DisplayName`: Also necessary for the Windows service.
* `property Active`: Indicates whether the server is listening. Useful for example for the UI of the VCL version or for the CLI of the console version.
* `property Port`: The port that can be modified from the VCL or console version.
* `procedure Start`: To activate the server.
* `procedure Stop`: To shut down the server.

## VCL Version

To create the VCL version, simply create a new VCL Application and instantiate the `TListener` object seen previously in the main form. You can add *start* and *stop* buttons to make them act on the respective methods of the *Listener* object. You can change the port, display the name and description of the applications by reading them from the *Name* and *DisplayName* properties.

Using filters it is also possible to create a log of calls to display directly on the form (see example `10.Filters`). We can create for example a simple `TListBox` and implement a method like this on the form:

```pascal
procedure TMainForm.Log(const AMsg: string);
begin
  TThread.Synchronize(nil,
    procedure ()
    begin
      lstLog.Items.Add(AMsg);
    end
  );
end;
```

It is important to note the use of `TThread.Synchronize`, this is because calls on the server in WiRL are handled on *threads* different from that of the GUI.

At this point two filters will suffice, one for requests and one for responses in order to send logs to the form. Here is an example for the request filter; the response one is practically identical.

```pascal
  interface

  uses
    ...;

  [PreMatching]
  TRequestLoggerFilter = class(TInterfacedObject, IWiRLContainerRequestFilter)
  private
    FMainForm: TMainForm;
  public
    procedure Filter(ARequestContext: TWiRLContainerRequestContext);
    constructor Create(MainForm: TMainForm);
  end;

implementation  

constructor TRequestLoggerFilter.Create(MainForm: TMainForm);
begin
  FMainForm := MainForm;
end;

procedure TRequestLoggerFilter.Filter(ARequestContext: TWiRLContainerRequestContext);
var
  LMessage: string;
begin
  LMessage := DateTimeToStr(Now) + ' - ' + ARequestContext.Request.Method + ' ' + ARequestContext.Request.PathInfo;
  if ARequestContext.Request.Query <> '' then
    LMessage := LMessage + '?' + ARequestContext.Request.Query;
  FMainForm.Log('REQ - ' + LMessage);
end;

initialization
  TWiRLFilterRegistry.Instance.RegisterFilter<TRequestLoggerFilter>(
    function (): TObject
    begin
      Result := TRequestLoggerFilter.Create(MainForm);
    end
  );

```

## Windows Service Version

For the Windows service version, you can start by creating the application skeleton using the Delphi wizard `File | New | Others... | Windows Service`. Delphi will create the project file and a unit with a class that derives from `TService`. As in the case of the VCL application, we will need to make the service instantiate and use `TListener`. For example:

```pascal
uses
  ...

type
  TmodService = class(TService)
    procedure ServiceExecute(Sender: TService);
  private
    FListener: TListener;
  public
    function GetServiceController: TServiceController; override;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  end;

var
  modService: TmodService;

implementation

{$R *.dfm}

procedure ServiceController(CtrlCode: DWord); stdcall;
begin
  modService.Controller(CtrlCode);
end;

constructor TmodService.Create(AOwner: TComponent);
begin
  inherited;
  FListener := TListener.Create;
  Name := FListener.Name;
  DisplayName := FListener.DisplayName;
end;

destructor TmodService.Destroy;
begin
  FListener.Free;
  inherited;
end;

function TmodService.GetServiceController: TServiceController;
begin
  Result := ServiceController;
end;

procedure TmodService.ServiceExecute(Sender: TService);
begin
  FListener.Start;
  while not Terminated do
  begin
    if Assigned(ServiceThread) then
      ServiceThread.ProcessRequests(False);
    Sleep(1000);
  end;
  FListener.Stop;
end;
```

The main changes are in the constructor, where the `TListener` object is created and then used to initialize the service name and description, and in the `ServiceExecute` method where the listener is started and remains active until the service is stopped.

## Console Version

Especially in a *Linux* environment it can be convenient to use a command line version of the application. In this case the code is particularly simple as it will be sufficient to create a function that instantiates the `TListener` and starts it. You can create the project skeleton from the `File | New | Console application` menu and call a procedure similar to the following:

```pascal
procedure RunListener;
var
  LListener: TListener;
begin
  LListener := TListener.Create;
  try
    LListener.Start;

    Writeln(LListener.Name);
    Writeln(LListener.DisplayName);
    Writeln(Format('http://localhost:%d/rest/app/demo', [LListener.Port]));
    Writeln('Press [enter] to exit');
    Writeln('');
    ReadLn;
    LListener.Stop;
    Writeln('Server stopped');
  finally
    LListener.Free;
  end;
end;

```

This code starts the server and, through `ReadLn`, waits for the enter key to be pressed and then closes the application. Obviously the function can be made more complex, for example to handle commands (port change, server startup, etc.), by reading the value returned by ReadLn and acting in some way.

## Docker Version

To run the WiRL application in *Docker*, you can use the console example seen previously. But due to how Docker works, it is more appropriate to prepare the program exit by intercepting the SIGINT signal (obtainable by pressing the CTRL-C keys, or through the kill command on Linux). To do this, simply replace the `ReadLn` instruction with a control loop where the signal in question is verified, for example like this:

```pascal
procedure RunListener;
var
  LListener: TListener;
begin
  LListener := TListener.Create;
  try
    LListener.Start;

    Writeln(LListener.Name);
    Writeln(LListener.DisplayName);
    Writeln(Format('http://localhost:%d/rest/app/demo', [LListener.Port]));
    Writeln('Press [CTRL-C] to exit');
    Writeln('');
    while True do
      try
        Sleep(1000);
      except
        on EControlC do
         Break;
      end;
    LListener.Stop;
    Writeln('Server stopped');
  finally
    LListener.Free;
  end;
end;

```

## Linux Daemon

On *Linux* it is possible to install the WiRL application using the console version, but there is a variant called *Daemon*. The difference between a console application and a Daemon is that the latter takes care of performing a series of operations that make the program more robust. In particular:

* fork the parent process and let it terminate
* setsid to create a new session detaching from its controlling terminal
* signals handling to catch/ignore signals
* fork again and let it terminate to ensure that you get rid of the session leading process
* close all open file descriptors inherited from the parent process
* redirect stdin, stdout, stderr to dev/null to ensure that the daemon doesn't crash
* chdir to change the working directory of the daemon
* umask to change the file mode mask according to the needs of the daemon

All these functionalities are offered by the `WiRL.Console.Posix.Daemon` unit and we can easily use them by creating a standard console application and calling the following function:

```pascal
procedure ExecuteDaemon;
var
  LListener: TListener;
begin
  LListener := TListener.Create;
  try

    TPosixDaemon.Setup(
      procedure (ASignal: TPosixSignal)
      begin
        case ASignal of
          TPosixSignal.Termination:
          begin
            LListener.Stop;
          end;

          TPosixSignal.Reload:
          begin
            // Reload configuration
            LListener.Port := 8080;
          end;
        end;
      end
    );
    LListener.Start;
    TPosixDaemon.Run(1000);
  finally
    LListener.Free;
  end;
end;
```

## Production Deployment

Once the application has been developed in the ways described above, it is possible to install it on the destination server, open the port where the application is listening and that's it.

However, this installation method is not recommended except in particularly protected environments or when you don't have special requirements. In all other cases it is better to make a real web server like Apache HTTP, nginx and others visible on the internet, and use reverse proxy functions to make the application endpoints visible externally.

In this way you can take advantage of a whole series of security controls performed by the web server (which WiRL does not do) and many advanced functionalities such as *load balancing*, *performance monitoring*, etc. that these systems make available.

For example with *Apache* a configuration like this is sufficient:

```
ProxyPass "/wirl/rest/" "http://localhost:1234/rest/"
ProxyPassReverse "/wirl/rest/" "http://localhost:1234/rest/"
ProxyPreserveHost On
```

With *nginx*, you can achieve the same result with this configuration:

```
location /wirl/rest/ {
    proxy_pass http://localhost:1234/rest/;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}
```

Both configurations ensure that when a resource beginning with `wirl/rest` is requested, it gets redirected to `http://localhost:1234/rest/` where, presumably, the WiRL server will be listening.# Entity Providers


## Entities in WiRL

In WiRL terminology Entities are simply data, often structured data (classes and records) but they can be of any Delphi type.

![Delphi Entities](./entities.png){class=center width=100%}

The main part of an HTTP interaction consists of the request and response entities. Entities are also referred to as the payload or message body in some contexts.

Entities are sent via a request, usually an HTTP `POST` and `PUT` method is used, or they are returned in a response, this is relevant for all the HTTP methods. The `Content-Type` HTTP header is used to indicate the type of entity being sent. Common content types are "text/plain", "text/xml", "application/json", and "application/pdf".

Media types are also used in the `Accept` header to indicate what type of resource representation the client wants to receive.


## Custom Entity Providers (MBR/W)

![Entity Providers](./entity-provider.png){class=center width=100%}

WiRL enables developers to add custom entity providers to the application. The custom entity providers can be used for dealing with user-defined classes in the requests as well as responses.

Adding a custom entity provider allows a way to deserialize user-defined classes from the message body and serialize any media type to your user specific class.

There are two types of entity providers:

- MessageBodyReader
- MessageBodyWriter

MessageBody Readers and Writers are crucial components in WiRL, serving as the bridge between HTTP request/response bodies and your application's data structures. They enable seamless conversion between various data formats and your Delphi objects, allowing you to focus on your business logic rather than low-level data parsing.

### MessageBodyReader

An application can provide an implementation of the `IMessageBodyReader` interface by implementing the `ReadFrom()` method to map the entity to the desired Delphi type.

The following figure shows how the MessageBodyReader reads a Request Stream and converts it to a user-defined Delphi object.

![MessageBodyReader](./mbr.png){class=center width=100%}

### MessageBodyWriter

The MessageBodyWriter interface represents a contract for a provider that supports the conversion from a Delphi type to a stream.

An application can provide an implementation of the `IMessageBodyWriter` interface by implementing the `WriteTo()` method to write the Delphi type to the Response Stream.

The following figure shows how MessageBodyWriter can take a user-defined class, Book, and marshal it to the Response's Stream object.

![MessageBodyReader](./mbw.png){class=center width=100%}

## How Do They Work

Suppose you define a resource in WiRL, like this:

```pascal
[Path('books')]
TBookResource = class
public
  [POST]
  [Consumes(TMediaType.APPLICATION_JSON)]
  [Produces(TMediaType.APPLICATION_JSON)]
  function NewBook([BodyParam] ABook: TBookProposal): TBook;
end;
```

The `Consumes` and `Produces` attributes state that you want the TBookProposal and TBook are in JSON format.

WiRL uses MessageBody Readers and Writers to handle the incoming and outgoing data:

1. **MessageBody Reader**: When a request arrives, WiRL looks for a reader that can transform the incoming JSON (specified by `Consumes(TMediaType.APPLICATION_JSON)`) into a `TBookProposal` object.

2. **Your Business Logic**: WiRL then calls your `NewBook()` method with the created `TBookProposal`.

3. **MessageBody Writer**: After your method returns a `TBook` object, WiRL finds a writer to convert it back to JSON (as specified by `Produces(TMediaType.APPLICATION_JSON)`).

## Content Negotiation

WiRL supports multiple `Consumes` and `Produces` attributes on a single resource. It selects the appropriate provider based on the request's `Content-Type` and `Accept` headers, allowing your API to be flexible with different data formats.

## Built-in Entity Providers

WiRL provides a variety of pre-built Entity Providers:

1. **Core Types** (WiRL.Core.MessageBody.Default):
   - Handles strings, simple types (integer, double, etc.), arrays, records, and objects (via the [Neon library plugin](neon)).
   - Supports streams and MultipartFormData.

2. **Data-aware Types** (WiRL.Data.MessageBody.Default):
   - Manages DataSets, DataSet arrays, and conversions to XML and CSV.

3. **FireDAC Specific** (WiRL.Data.FireDAC.MessageBody.Default):
   - Provides readers and writers tailored for FireDAC components.

4. **UniDAC Specific** (WiRL.Data.UniDAC.MessageBody.Default):
   - Provides readers and writers tailored for UniDAC components.

## Using Built-in Entity Providers

To use these pre-built providers, simply include the necessary units in your project:

```pascal
uses
  WiRL.Core.MessageBody.Default,
  WiRL.Data.MessageBody.Default,
  WiRL.Data.FireDAC.MessageBody.Default;
```

This inclusion automatically registers the readers and writers with WiRL, making them available for use in your resources.

## Custom Entity Providers

While WiRL provides a comprehensive set of built-in entity providers, you can also create custom ones for specific needs. This allows you to handle unique data formats or complex object transformations tailored to your application.

## Conclusion

Entity Providers in WiRL provide a powerful abstraction layer, handling the complexities of data transformation between HTTP and your application's domain objects. By leveraging these components, you can create clean, type-safe REST APIs while maintaining flexibility in data formats and focusing on your core business logic.# Exception handling

WiRL provides a robust mechanism for handling exceptions in your web applications. This chapter will walk you through the various ways you can manage and customize error responses.

## The Importance of Exception Handling

Exception handling is critical in a REST server library like WiRL. When developing web applications, errors can originate from various sources: invalid client requests, business logic constraints, database issues, or unexpected run-time errors. Proper exception handling ensures that:

* Clients receive meaningful error information in a consistent format
* Sensitive internal error details are not inadvertently exposed
* Application stability is maintained despite errors
* Debugging and troubleshooting are facilitated through appropriate error messages

WiRL's exception handling framework addresses these needs through a layered approach, giving you both automatic protection and customization options.

## Default Exception Handling

By default, WiRL catches all unhandled exceptions that occur during request processing. When an uncaught exception occurs, WiRL automatically:

1. Intercepts the exception
2. Converts it to an appropriate HTTP status code (generally 500)
3. Generates a standardized JSON response with key error information

The response body will be a JSON object with the following structure:

```json
{
  "status": 500,
  "exception": "EDivByZero",
  "message": "Division by zero"
}
```

The exception field contains the name of the exception class, while the message field contains the exception message.
This automatic handling ensures that even unexpected errors don't crash your server and that clients always receive a properly formatted response. The default JSON error response includes essential details like error message, exception type, and status code.

## Custom Exception Responses

For more control over the error response, you can use the `EWiRL­Web­Application­Exception` class. This allows you to specify a custom message and HTTP status code. For example:

```pascal
function TDemoResource.GetError: string;
begin
  raise EWiRLWebApplicationException.Create('Invalid input', 400);
end;
```

This will produce the following JSON response:

```json
{
  "status": 400,
  "exception": "EWiRLWebApplicationException",
  "message": "Invalid input"
}
```

### Adding Additional Data

For more control over error responses, WiRL provides a specialized exception type: `EWiRL­Web­Application­Exception`. By raising this exception in your code, you can:

* Set the specific HTTP status code to return
* Include custom error messages
* Add application-specific data to the error response
* Provide structured information to help clients handle the error appropriately. 

You can do this either by providing a JSON object or by using the fluent `ExceptionValue` syntax:

```pascal
function TDemoResource.GetError: string;
begin
  raise EWiRLWebApplicationException.Create('Invalid input', 400,
    TValuesUtil.MakeValueArray(
      Pair.S('unit', 'Test.pas'), // String value
      Pair.N('Line', 150)         // Numeric value
    )
  );
end;
```

This will generate the following response:

```json
{
  "status": 400,
  "exception": "EWiRLWebApplicationException",
  "message": "Invalid input",
  "data": {
    "unit": "Test.pas",
    "Line": 150
  }
}
```

The Pair object supports various data types:

* `S` for strings
* `N` for numeric values
* `D` for TDateTime
* `B` for boolean values

### Pre-defined Exception Classes

WiRL provides several pre-defined exception classes that derive from `EWiRL­Web­Application­Exception`. These classes automatically set the appropriate HTTP status code:

**Client Errors** 

* EWiRLBadRequestException: 400
* EWiRLNotAuthorizedException: 401
* EWiRLNotFoundException: 404
* EWiRLNotAcceptableException: 406
* EWiRLUnsupportedMediaTypeException: 415

**Server Errors**

* EWiRLServerException: 500
* EWiRLNotImplementedException: 501

## Exception Mappers

Sometimes you might want to associate a HTTP error code and response with a specific exception, including standard or third-party exceptions. For instance, you might want to map a dataset's "required field" exception to a 400-series error instead of the default 500 or expose some information in the JSON response.

To achieve this, you can use an exception mapper. Here's how to create and use one:

  1. Create a class that inherits from `TWiRLExceptionMapper` and implement the `HandleException` method:

```pascal
TFieldRequiredErrorMapper = class(TWiRLExceptionMapper)
public
  procedure HandleException(AExceptionContext: TWiRLExceptionContext); override;
end;

procedure TFieldRequiredErrorMapper.HandleException(
  AExceptionContext: TWiRLExceptionContext);
const
  StatusCode = 400;
var
  MyException: EFieldRequiredError;
  LJSON: TJSONObject;
begin
  inherited;
  MyException := AExceptionContext.Error as EFieldRequiredError;
  LJSON := TJSONObject.Create;
  try
    EWiRLWebApplicationException.ExceptionToJSON(MyException, StatusCode, LJSON);
    LJSON.AddPair(TJSONPair.Create('ErrorCode', TJSONNumber.Create(MyException.ErrorCode)));
    AExceptionContext.Response.StatusCode := StatusCode;
    AExceptionContext.Response.ContentType := 'application/json';
    AExceptionContext.Response.Content := TJSONHelper.ToJSON(LJSON);
  finally
    LJSON.Free;
  end;
end;
```

2. Register the exception mapper:

```pascal
TWiRLExceptionMapperRegistry.Instance.RegisterExceptionMapper<TFieldRequiredErrorMapper, EFieldRequiredError>();
```

By using exception mappers, you can customize how WiRL handles specific exceptions, providing more meaningful and appropriate responses to your API clients.

### Global exception mapper

By registering an exception mapper for the `Exception` class, you're providing a catch-all handler for any exception that doesn't have a more specific mapper. This allows you to completely customize how WiRL generates error responses for all exceptions. This approach is particularly useful when you want to:

* Ensure a consistent error response format across your entire application.
* Add additional debugging information to all error responses.
* Implement logging or error tracking for all exceptions.
* Mask internal error details in production environments.# Filters for Requests and Responses

Filters are powerful components in WiRL that allow you to intercept and modify HTTP requests and responses at various stages of processing. They provide a flexible way to implement cross-cutting concerns such as **logging**, **authentication**, **compression**, and custom **header management** without modifying your resource classes. With filters, you can both monitor specific events (request arrival and response generation) and actively **transform the request and response** content. This dual capability enables you to implement sophisticated request validation, content transformation, or response enrichment without cluttering your core resource logic.

Filters can be configured to intercept specific events in the request-response lifecycle, such as **pre-processing** (before the request reaches your resource), **post-processing** (after your resource generates a response but before it's sent to the client), or error handling. During these interception points, filters have full access to modify both the incoming requests (changing headers, query parameters, or request body) and outgoing responses (altering status codes, adding headers, or transforming the response payload). This event-driven architecture allows for precise control over the HTTP communication flow while maintaining clean separation of concerns in your application.

### Response filters

Response filters provide a way to manipulate the HTTP response after your resource methods have completed their processing. This makes them ideal for implementing consistent response modifications across multiple endpoints, such as adding standard headers, compressing response content, or formatting response data. 

The following example shows a response filter adding a header to each response.

```pascal
interface

type
  TResponsePoweredByFilter = class(TInterfacedObject, IWiRLContainerResponseFilter)
  public
    procedure Filter(AResponseContext: TWiRLContainerResponseContext);
  end;

implementation

procedure TResponsePoweredByFilter.Filter(AResponseContext: TWiRLContainerResponseContext);
begin
  if AResponseContext.Response.StatusCode >= 500 then
    AResponseContext.Response.HeaderFields['X-Powered-By'] := 'DataSnap' // ;-)
  else
    AResponseContext.Response.HeaderFields['X-Powered-By'] := 'WiRL';
end;

initialization
  TWiRLFilterRegistry.Instance.RegisterFilter<TResponsePoweredByFilter>;

```

The filter must implement the `IWiRLContainerResponseFilter` interface and must be registered. This is a *response filter* so it's executed after the ReST resource does its work, also if the resource raises an exception.

### Request filters

Request filters intercept incoming HTTP requests before they reach your resource methods, allowing you to validate, modify, or reject requests based on custom logic. You can use request filters to implement security checks, request preprocessing, or to enforce business rules. If a request filter raises an exception, the resource method won't be invoked, making request filters an excellent place to implement validation logic.

The following example shows a request filter that checks the value of a custom HTTP header.

```pascal
interface

type
  TRequestCheckerFilter = class(TInterfacedObject, IWiRLContainerRequestFilter)
  public
    procedure Filter(ARequestContext: TWiRLContainerRequestContext);
  end;

implementation

procedure TRequestCheckerFilter.Filter(ARequestContext: TWiRLContainerRequestContext);
begin
  if Pos('error', ARequestContext.Request.Query) > 0 then
    raise EWiRLWebApplicationException.Create(Format('Filter error test [%s]', [FApplication.Name]), 400);
end;

initialization
  TWiRLFilterRegistry.Instance.RegisterFilter<TRequestCheckerFilter>;

```

This filter is triggered only when the resource has been successfully located. Additionally, if the filter raises an exception, the REST resource method is not called, preventing the execution of the resource code.

## Pre-matching filters

The previous examples would be applied only after a suitable resource method has been selected to process the actual request. If you want a filter that runs *before* the resource matching you must use a Pre-matching filters. In this case you have to simply decorate the filter with the `PreMatching` attribute.

```pascal
type
  [PreMatching]
  TRequestLoggerFilter = class(TInterfacedObject, IWiRLContainerRequestFilter)
  public
    procedure Filter(ARequestContext: TWiRLContainerRequestContext);
  end;
```

## Name binding

Something can be useful to invoke a filter only to some of the resource methods. What you need is simply a brand new attribute that decorates both the filter class and the resource methods. The attribute itself must be decorated with the `NameBinding` attribute (seems tricky but isn't).

```pascal
type
  // I declare the new attribute
  [NameBinding]
  ContentEncodingAttribute = class(TCustomAttribute);

  // I use the new attribute to decorate the filter
  // than I must decorate the resource method with the same attribute
  [ContentEncoding]
  TResponseEncodingFilter = class(TInterfacedObject, IWiRLContainerResponseFilter)
  private
    const ENC_GZIP = 'gzip';
    const ENC_DEFLATE = 'deflate';
    const ENC_IDENTITY = 'identity';
  public
    procedure Filter(AResponseContext: TWiRLContainerResponseContext);
  end;
```

## Priorities

In a complex application you can have more filter before and after a resource method and you have to choose the exact order in which they are invoked. With WiRL this is possible with the `Priority` attribute that must be used to decorate the filter class. There are some predefined priorities but you can define any value you like:

* AUTHENTICATION
* AUTHORIZATION
* HEADER_DECORATOR
* ENTITY_CODER
* USER (*default*)

The filters are first ordered by theirs priority and then invoked.

```pascal
  [Priority(TWiRLPriorities.AUTHORIZATION)]
  TAuthorizationFilter = class(TInterfacedObject, IWiRLContainerRequestFilter)
  public
    procedure Filter(ARequestContext: TWiRLContainerRequestContext);
  end;
```

## Context Injection

When implementing filters in WiRL, both request and response filters provide access to context objects (`TWiRL­Container­Request­Context` or `TWiRL­Container­Response­Context`) through their Filter method parameters. These context objects give you access to essential information about the HTTP transaction, such as URL, headers, message body, and HTTP method.

However, WiRL offers an even more powerful approach through context injection. Just as with resource classes and methods, you can leverage dependency injection in your filters to access various contextual objects without manually extracting them from the context parameter.

Using context injection in filters follows the same principles as described in the *Context Injection chapter*. You can inject parameters directly into your filter's constructor or declare them as properties with appropriate attributes. This approach makes your filter code cleaner and more focused on its specific responsibility.

Here's an example of using context injection in a request filter:

```pascal
type
  TMyInjectedFilter = class(TInterfacedObject, IWiRLContainerRequestFilter)
  private
    [Context] FApplication: TWiRLApplication;
    [Context] FRequest: TWiRLRequest;
    [Context('SecurityContext')] FSecurity: TMySecurityContext;
  public
    procedure Filter(ARequestContext: TWiRLContainerRequestContext);
  end;

implementation

procedure TMyInjectedFilter.Filter(ARequestContext: TWiRLContainerRequestContext);
begin
  // Now you can directly use FApplication, FRequest and FSecurity
  // instead of extracting them from ARequestContext
  
  if not FSecurity.IsAuthorized(FRequest.PathInfo) then
    raise EWiRLWebApplicationException.Create('Unauthorized access', 401);
    
  // Log request information
  FApplication.Logger.Log('Request received: ' + FRequest.PathInfo);
end;
```

With context injection, your filters can seamlessly access the same contextual objects available to your resource methods. This includes:

* `TWiRLApplication` - The current WiRL application instance
* `TWiRLRequest` and `TWiRLResponse` - The HTTP request and response objects
* `TWiRLURIInfo` - Information about the parsed URI
* Custom context objects - Any custom objects you've registered with the context
  
Context injection promotes cleaner code organization and better separation of concerns in your filters, making them more maintainable and easier to test. It's particularly valuable for filters that need access to application-specific services or security contexts.# Memory Management in WiRL

In most scenarios, **WiRL handles memory management automatically**, freeing developers from the burden of manual object cleanup. However, there are specific cases where understanding the memory management process becomes crucial. This chapter will explore these particular situations, helping you prevent memory leaks and avoid the unintended destruction of objects that need to persist.

As Delphi developers, we're accustomed to manual memory management, with some familiar pattern of creating objects and ensuring their proper destruction when no longer needed. WiRL, however, introduces some peculiarities. Resources in WiRL are typically methods that return objects, and for the framework to function correctly, these objects generally shouldn't be destroyed manually, WiRL takes care of this automatically.

But real-world scenarios can be more complex. What happens if an **exception** occurs after an object is created—who handles its destruction then? What about returned objects with **dependencies**, such as a dataset that relies on an active connection? These edge cases require careful consideration to prevent memory leaks and ensure proper resource cleanup.

## Basic Concept

When writing REST resources with WiRL, you typically create methods that return objects. For example:

```pascal
[Path('order')]
TOrderResource = class
public
  [POST]
  [Consumes(TMediaType.APPLICATION_JSON)]
  [Produces(TMediaType.APPLICATION_JSON)]
  function PostOrder([BodyParam] AOrderProposal: TOrderProposal): TOrder;
end;
```

In this case, WiRL takes care of destroying the `TOrder` object when it's no longer needed (i.e., after composing the response). However, there are some scenarios that require special attention.

## Handling Exceptions

Consider this implementation:

```pascal
function TOrderResource.PostOrder(AOrderProposal: TOrderProposal): TOrder;
begin
  Result := TOrder.Create;
  Result.OrderId := AOrderProposal.OrderId;
  // Etc.
end;
```

If an exception occurs after creating `TOrder`, a memory leak will occur. To prevent this, you can use the following pattern:

```pascal
function TOrderResource.PostOrder(AOrderProposal: TOrderProposal): TOrder;
begin
  Result := TOrder.Create;
  try
    Result.OrderId := AOrderProposal.OrderId;
    // Etc.
  except
    Result.Free;
    raise;
  end;  
end;
```

This ensures that the object is released in case of an exception; otherwise, WiRL will handle its destruction.

## Using WiRL's Garbage Collector

An alternative approach is to use WiRL's built-in garbage collector (`TWiRLGarbageCollector`). You can obtain an instance through [context injection](context-injection):

```pascal
[Path('order')]
TOrderResource = class
private
  [Context] 
  GC: TWiRLGarbageCollector;
public
  [POST]
  [Consumes(TMediaType.APPLICATION_JSON)]
  [Produces(TMediaType.APPLICATION_JSON)]
  function PostOrder([BodyParam] AOrderProposal: TOrderProposal): TOrder;
end;
```

Now you can rewrite your method as follows:

```pascal
function TOrderResource.PostOrder(AOrderProposal: TOrderProposal): TOrder;
begin
  Result := TOrder.Create;
  GC.AddGarbage(Result);
  Result.OrderId := AOrderProposal.OrderId;
  // Etc.
end;
```

This way, the `TOrder` instance is immediately passed to the garbage collector. WiRL will handle its destruction, even if problems occur later.

## Managing Long-Lived Objects

The garbage collector is also useful for objects that need to live longer than the resource method. Consider this example:

```pascal
function CustomerList: TDataSet;
var
  LConnection: TMyConnection;
begin
  LConnection := TMyConnection.Create;
  // Configure connection
  Result := TMyDataSet.Create(nil);
  Result.Connection := LConnection;
  Result.Open;
end;
```

Here, `TMyConnection` isn't destroyed because WiRL needs it to serialize the dataset after the method ends. However, WiRL doesn't know about the `TMyConnection` object and this will cause a memory leak. The garbage collector solves this:

```pascal
function CustomerList: TDataSet;
var
  LConnection: TMyConnection;
begin
  LConnection := TMyConnection.Create;
  GC.AddGarbage(LConnection);
  Result := TMyDataSet.Create(nil);
  GC.AddGarbage(Result);
  Result.Connection := LConnection;
  Result.Open;
end;
```

## Handling Singletons and Global Objects

Sometimes your resource needs to return an object that shouldn't be destroyed, like a singleton or a global object. In this case, decorate the method or class with the `[Singleton]` attribute:

```pascal
[Path('order')]
TOrderResource = class
public
  [GET]
  [Produces(TMediaType.APPLICATION_JSON)]
  [Singleton]
  function GetOrder([QueryParam('id') AId: Integer]): TOrder;
end;
```

This prevents WiRL from destroying the returned object.

## Conclusion

Proper memory management in WiRL involves understanding when and how objects are created and destroyed. By using try-except blocks, leveraging the garbage collector, and applying the `[Singleton]` attribute where necessary, you can ensure your WiRL applications manage memory efficiently and avoid leaks.# Neon Integration

[Neon](https://github.com/paolo-rossi/delphi-neon) is a powerful serialization library for Delphi that facilitates the conversion of objects and other values to and from JSON. It supports simple Delphi types as well as complex classes and records.

::: tip DEMO
You can find a demo demonstrating how serialize complex objects in the `demo\13.Serialization` folder.
:::

## WiRL and Neon Integration

WiRL seamlessly integrates with Neon through its default [Entity Providers](entity-providers). This integration allows automatic serialization and deserialization of objects in request bodies and response returns.

## Configuring Neon in WiRL

You can customize Neon's behavior in WiRL using the official plugin interface. Here's an example of how to configure Neon within your WiRL server setup:

```pascal
RESTServer := TWiRLServer.Create(Self);
RESTServer.AddEngine<TWiRLEngine>('/rest')
  .SetEngineName('RESTEngine')
  .AddApplication('/app')
    .SetResources('*')
    .SetFilters('*')
    // Neon plugin configuration
    .Plugin.Configure<IWiRLConfigurationNeon>
      .SetUseUTCDate(True)
      .SetVisibility([mvPublic, mvPublished])
      .SetMemberCase(TNeonCase.PascalCase);
StartServerAction.Execute;
```

## Configurable Parameters

Neon's behavior can be fine-tuned using various parameters. Each parameter is set using a corresponding `Set<ParameterName>` function. Here are the key parameters:

### Members
- `Fields`: Serialize/deserialize object fields
- `Properties`: Consider only object properties

### MemberCase
Controls how property names are formatted in JSON:
- `Unchanged`: Leaves names as-is
- `LowerCase`: Converts to all lowercase (propertyname)
- `UpperCase`: Converts to all uppercase (PROPERTYNAME)
- `PascalCase`: Capitalizes the first letter of each word (PropertyName)
- `CamelCase`: Like PascalCase, but keeps the first letter lowercase (propertyName)
- `SnakeCase`: Separates words with underscores (property_name)
- `KebabCase`: Separates words with hyphens (property-name)
- `ScreamingSnakeCase`: Like SnakeCase, but in all uppercase (PROPERTY-NAME)
- `CustomCase`: Uses a custom function specified by `MemberCustomCase`

### MemberCustomCase
Allows you to specify a custom function for property name conversion.

### Visibility
Determines which class members to include based on their visibility:
- `mvPrivate`: Includes private variables
- `mvProtected`: Includes protected variables
- `mvPublic`: Includes public variables
- `mvPublished`: Includes published variables

### UseUTCDate
When set to `True`, treats dates as UTC.

### PrettyPrint
When enabled, generates more readable (but larger) JSON output.

## Best Practices

1. **Choose appropriate visibility**: Typically, using `mvPublic` and `mvPublished` is sufficient and secure for most applications.

2. **Consider date handling**: If your application deals with multiple time zones, setting `UseUTCDate` to `True` can help maintain consistency.

3. **Balance readability and performance**: While `PrettyPrint` makes JSON more readable, it increases payload size. Use it judiciously, especially in high-traffic scenarios.

4. **Consistency in naming**: Choose a `MemberCase` that aligns with your API design principles and stick to it across your application.
# OpenAPI Documentation

If you ever developed a public **REST API** you know that you have to provide the users of the API with some documentation so they can write the client in their language of choice.

Of couse you can write your documentation manually and publish to some website, but you have to continuously sync the documentation with the changes to your API endpoints, parameters, entities, etc... and you know that it can be an exhausting task! :-)

**WiRL** tries to build this documentation for you using the code itself, the attributes used to decorate the resource classes, the XMLDoc documentation, etc...

::: tip :book: OpenAPI Demo
You can find a demo generating OpenAPI documentation in the `demo\18.OpenAPI` folder. Play with it do discover more!
:::

## What is OpenAPI?

**OpenAPI** is a specification format that is used to define **REST APIs**. It uses **JSON Schema** to describe the API's calls and data. OpenAPI documents can establish a contract between the API consumer and producer, they can be used to generate documentation, mock servers, client SDKs, and API tests.

An **OpenAPI document** describes the API without requiring access to the source code or additional documentation. The specification is both human and machine readable.

OpenAPI documents can be created with a code editor or an API design tool in the early phases of the API lifecycle, or they can be **generated from existing API code**.

## History of OpenAPI

**OpenAPI** or **OAS** (Open API Specification) was previously known as **Swagger** specification:

- The developed began in 2011 by Tony Tam.
- In 2015 SmartBear acquired the Swagger API specification.
- In November 2015 SmartBear donated the Swagger specification to a new organization called the **OpenAPI Initiative**, under the sponsorship of the **Linux Foundation**. Other founding member of the **OpenAPI Initiative** includes Apigee, Google, IBM, Intuit, Microsoft, and PayPal.
- In 2016 the Swagger specification was renamed the **OpenAPI Specification (OAS)** and was moved to a new [GitHub repository](https://github.com/OAI/OpenAPI-Specification).
- In July 2017, the **OpenAPI Initiative** released the 3.0 version of the specification.


### OpenAPI vs Swagger

OpenAPI documents are sometimes referred as **Swagger** documents but remember that OAS 3.x documents are the true standard for APIs documentation and the old Swagger 2.0 version is now deprecated.

## The OpenAPI Library

In order to generate **OAS 3.0** document WiRL uses the open source library [OpenAPI-Delphi](https://github.com/paolo-rossi/OpenAPI-Delphi).

With **OpenAPI-Delphi** you can  use the `TOpenAPIDocument` class to fill the document's properties and then you can serialize the object into an OAS 3 JSON document using [Neon](https://github.com/paolo-rossi/delphi-neon) JSON Schema Engine. 

With the OpenAPI library you can also deserialize an OAS 3.0 JSON document directly in a `TOpenAPIDocument` object.

Remember that the **OpenAPI-Delphi** library is independent from WiRL or REST related stuff, you can use it even in your stand-alone Delphi application.


## WiRL & OpenAPI

So, now that you have your new, shiny **REST API service**, what do you have to do in order to generate the OpenAPI documentation in WiRL? Here are the foundamental steps:

::: warning Steps

1. Configure/modify the OpenAPI resource
1. Create the `TOpenAPIDocument` object with custom information
1. Enable the "Generate XML Documentation" in Delphi Project Options \*
1. Configure the "XML documentation output directory" in Delphi Project Options \*
1. Deploy the XMLDoc folder on the server \*
1. Configure and deploy the html assets for the browsing UI \**


\* *Only if you want to use XMLDoc as source of your OpenAPI documentation*

\** *Only if you want to provide an HTML UI to browse your documentation*

:::

### The OpenAPI Resource

WiRL provides a ready-to-use resource mapped on the `/openapi` path (you can override it), you can find this resource in the `WiRL.Core.OpenAPI.Resource` unit.
You can override the standard resource for OpenAPI by inheriting from the `TOpenAPIResourceCustom` class and change, for example, the standard path for the resource:

```pascal
type
  [Path('documentation')]
  TDocumentationResource = class(TOpenAPIResourceCustom);
```

### The `TOpenAPIDocument`

The `TOpenAPIDocument` is a class that models an OpenAPI document (or set of documents) that defines or describes an API. The OpenAPI engine in WiRL creates and fill the properties with data taken from the source code or XMLDoc comments but there are certains things that you have (optionally) to provide for yourself, for example look at the following code that create and set some properties of the document:

```pascal
function TMainForm.ConfigureOpenAPIDocument: TOpenAPIDocument;
var
  LExtensionObject: TJSONObject;
begin
  Result := TOpenAPIDocument.Create(TOpenAPIVersion.v303);

  Result.Info.TermsOfService := 'https://api.example.com/terms/';
  Result.Info.Title := 'WiRL OpenAPI Integration Demo';
  Result.Info.Version := '1.0.2';
  Result.Info.Description := 'This is a **demo API** to test [WiRL](https://github.com/delphi-blocks/WiRL) OpenAPI documentation features';
  Result.Info.Contact.Name := 'Paolo Rossi';
  Result.Info.Contact.Email := 'paolo@mail.it';
  Result.Info.License.Name := 'Apache 2.0';
  Result.Info.License.Url :=  'http://www.apache.org/licenses/LICENSE-2.0.html';

  Result.AddServer('http://localhost:8080/rest/app', 'Testing Server');
  Result.AddServer('https://api.example.com/rest/app', 'Production Server');

  // Shows how to use Extensions (for ReDoc UI)
  LExtensionObject := TJSONObject.Create;
  LExtensionObject.AddPair('url', 'http:.//localhost:8080/rest/app/openapi/api-logo.png');
  LExtensionObject.AddPair('backgroundColor', '#FFFFFF');
  LExtensionObject.AddPair('altText', 'API Logo');
  Result.Info.Extensions.Add('x-logo', LExtensionObject);
end;
```

A small note on the `TOpenAPIDocument.AddServer` method:

Some OAS editor and UI have a "Try Out" feature where you can interact directly with the REST server in order to try the API calls live. Of course then you need to configure the server(s) on the OAS document like I did in the code above, you can also put more than one like, for example, a testing server and a production server.

### Using Delphi XMLDoc

WiRL can extract most information directly from the REST code (resource classes and annotations) but what if you want add some descriptive text, explanations, remarks? Well you can simply do it by commenting the REST methods, parameters, method result, and result http codes.

The way to do this is to use the XMLDoc wich is the standard comment style in Delphi for many years. You can use markdown style comments to improve the document appereance, link ein this code fragment:

```pascal
  /// <summary>
  ///   This **resource** serves to test the *OpenAPI 3* documentation generation
  /// </summary>
  [Path('/params')]
  TParametersResource = class(TObject)
```

You can also extend the standard XMLDoc tags (summary, param, returns, remarks) with some WiRL specific tags: response code, url, example.

```pascal
  /// <summary>
  ///   Method with a *sample* documentation
  /// </summary>
  /// <param name="APathParam" required="true">
  ///   The first parameter
  /// </param>
  /// <returns>
  ///   Result is a string representing the input parameter
  /// </returns>
  /// <remarks>
  ///   Here is a sample remarks placeholder.
  /// </remarks>
  /// <response code="200">Succesful response description</response>
  ///  <header name="X-Header" type="string">Description of the header</header>
  /// <response code="400">Bad request</response>
  /// <response code="404">[resource] not found in the database</response>
  [GET, Path('/test/{p}'), Produces(TMediaType.TEXT_PLAIN)]
  function ParamTest([PathParam('p')] APathParam: string): string;
```

### The Presentation UI (HTML)

After proper configuration for the OAS documentation generation, WiRL it's able to generate and output a JSON document representing the OAS 3.0 description of all endpoints, parameters, and entities that your API publishes.

A consumer of the API can take this JSON document and use it to generate it's own documentation about your API, although, perhaps you prefer to publish the documentation with a UI you can interact with.

If you want do do this you have to deploy some html, javascript, and css that can manage and present the data of the OAS JSON document.

WiRL provide you with a copy of a redistributable UI from Swagger ([**SwaggerUI**](https://github.com/swagger-api/swagger-ui)) that you can deploy on your server, look at the highlighted configuration line:

```pascal{3}
.Plugin.Configure<IWiRLConfigurationOpenAPI>
	...
	.SetGUIDocFolder('{AppPath}\..\..\UI')
.ApplyConfig
```

You can also add additional information like, for example setting a logo for your documentation page: `SetAPILogo('api-logo.png')`.

## The Final Configuration

Here is a final example of a simple OpenAPI configuration in WiRL:

```pascal
.Plugin.Configure<IWiRLConfigurationOpenAPI>
	// Set the OpenAPI resopource (in order to skip it in the documentation generation)
	.SetOpenAPIResource(TDocumentationResource)
	// Set the Delphi XML documentation output directory (Project -> Options -> Compiler)
	.SetXMLDocFolder('{AppPath}\..\..\Docs')
	// Set the folder where the html UI assets are
	.SetGUIDocFolder('{AppPath}\..\..\UI')
	// Set the (optional) API logo
	.SetAPILogo('api-logo.png')
	// Set the OpenAPI document for the OpenAPI engine to fill
	.SetAPIDocument(LDocument)
.ApplyConfig
```

## The OAS document in SwaggerUI

The following image is an example of an API documentation presented by the SwaggerUI interface

![OpenAPI Document](./openapi-ui.png){class=center width=100%}
# WiRL Service Deployment

A REST API built with WiRL offers remarkable flexibility in deployment, allowing developers to choose the best option based on their operating system, infrastructure, and operational requirements. This ensures that WiRL services can seamlessly integrate into diverse environments, from local development machines to enterprise-grade production servers and cloud-native setups.

## WiRL REST Services Deployment Options

WiRL-based REST APIs can be deployed in several common and specialized ways:

1.  **Standalone GUI Server (Windows):** For quick setup, internal tools, or transitioning existing applications.
2.  **Windows Service App (Windows):** The traditional and robust choice for production deployments on Windows.
3.  **Console Application (Windows and Linux):** A versatile option for both debugging and production, across multiple OS.
4.  **Docker Container (Windows and Linux):** Embracing modern containerization for scalability, portability, and DevOps practices.
5.  **Daemon Service (Linux):** The optimal solution for native, production-ready deployments on Linux systems.

-----

### Standalone GUI Server

This deployment method allows you to package your WiRL REST API directly within a standard Delphi GUI application, whether it's a VCL application for Windows or a FireMonkey (FMX) application for Windows, macOS, Android, or iOS. The application, once launched, will listen on a configured HTTP port, ready to receive and process incoming HTTP requests.

  * **Use Cases:**
      * **Rapid Development and Debugging:** Ideal during the development phase for quick testing and debugging of API endpoints.
      * **Internal Services:** Suitable for services that are consumed within a controlled local network or by a limited number of known clients.
      * **Transforming Existing C/S Applications:** A powerful way to incrementally modernize traditional Client/Server Delphi applications by exposing existing business logic as RESTful endpoints, allowing new clients (e.g., web or mobile frontends) to consume them without a full rewrite.
  * **Platform Support:**
      * **Windows:** Fully supported via VCL.
      * **Cross-Platform:** Supported on Windows, macOS, Android, and iOS via FMX, making it viable for deploying small, self-contained REST services on a variety of desktop and mobile platforms if the use case allows.

-----

### Windows Service App

Leveraging Delphi's built-in support for Windows Services, this deployment option allows you to run your WiRL REST service as a background process on Windows operating systems. This is the **go-to choice for production environments** on Windows due to its inherent features:

  * **Reliability:** Services can be configured to start automatically when the system boots, ensuring high availability.
  * **Background Operation:** They run independently of any logged-in user session, making them ideal for server environments.
  * **Administrative Control:** Full integration with Windows Service Manager, allowing for easy starting, stopping, pausing, and configuring of the service.
  * **Recovery Options:** Built-in mechanisms to automatically restart the service in case of failure.
  * **Security Context:** Services can run under specific user accounts with precisely defined permissions, enhancing security.
  * **Delayed Start:** Option to delay service startup, allowing critical system components to initialize first.
  * **Platform Support:** This option is exclusively available for the **Windows operating system**.

-----

### Console Application

WiRL offers comprehensive support for building console-based REST services through its `WiRL.Console.*` namespace. This deployment type creates a command-line executable that can run your REST service.

  * **Versatility:** Recommended for both **debugging and production deployment**. Its console interface provides a convenient way to monitor the service's status and interact with it (e.g., display menu options for management, graceful shutdown).
  * **Headless Operation:** Ideal for server environments where a graphical user interface is not required or desired.
  * **Scriptability:** Easily integrated into batch scripts or shell scripts for automated deployment and management.
  * **Platform Support:** A significant advantage is its availability for **all operating systems that Delphi supports**, including Windows and Linux, making it a highly portable deployment choice.

-----

### Docker Container

WiRL 4.7 introduced robust support for dockerized applications, specifically designed for console-based WiRL services. This enables you to encapsulate your WiRL REST API within a Docker container, unlocking the numerous benefits of containerization:

  * **Portability:** Build once, run anywhere. Docker containers package your application and all its dependencies, ensuring it runs consistently across different environments (development, testing, production).
  * **Isolation:** Containers provide process and resource isolation, preventing conflicts between applications and ensuring stable operation.
  * **Scalability:** Easily scale your services horizontally by spinning up multiple instances of your container.
  * **Resource Efficiency:** Containers are more lightweight than traditional virtual machines, leading to better resource utilization.
  * **DevOps Friendly:** Integrates seamlessly into CI/CD pipelines for automated builds, testing, and deployment.
  * **Microservices Architecture:** A perfect fit for microservices deployments, where each service runs in its own isolated container.
  * **High Recommendation:** Highly recommended for **production service deployment** due to its inherent advantages in modern cloud and DevOps environments.
  * **Platform Support:** Supported on any platform that can run container applications, including **Windows and Linux**, as Docker is cross-platform.

-----

### Daemon Service

WiRL stands out as one of the few (if not the only) Delphi libraries that natively supports the creation of a **Linux Daemon** that strictly adheres to Linux daemon best practices. This is a critical feature for deploying production-ready services on Linux machines.

  * **Native Linux Integration:** A true daemon detaches from the controlling terminal, runs in the background, handles signals correctly, and manages its process ID (PID) file, conforming to `/etc/init.d` or `systemd` standards.
  * **Robustness:** Provides the same level of reliability and manageability on Linux as Windows Services do on Windows.
  * **Optimal for Production:** If your target environment is a production-grade Linux server, this option is **the best for you** due to its native design and robust operational characteristics.
  * **Platform Support:** This type of deployment is specifically supported only by the **Linux operating system**.

-----

## Service Security: Beyond the Basics

While Delphi's Indy Library does offer OpenSSL integration for enabling SSL/TLS on the WiRL server component, relying solely on Indy for production-grade SSL can come with limitations. Indy uses `libeay32.dll` and `ssleay32.dll` (from OpenSSL 1.0.x series), which may lack support for newer TLS versions, stronger cipher suites, and more advanced security features that are now considered essential for modern web security. Managing certificates, keys, and specific OpenSSL versions can also be complex.

**So, how to effectively secure your WiRL services with all the modern standards?**

The easiest and most recommended way is to deploy your WiRL service **behind a reverse proxy**. This architectural pattern is a standard industry best practice for securing and managing web services.

### Reverse Proxy Deployment Explained

A reverse proxy (such as Nginx, Apache HTTP Server, IIS Application Request Routing (ARR), Caddy, Traefik, HAProxy, etc.) sits in front of your WiRL service.

1.  **External Request (HTTPS):** When an external client makes a request to your API, it sends it over HTTPS (encrypted) to the reverse proxy.
2.  **Reverse Proxy's Role:**
      * **SSL Termination:** The reverse proxy handles the demanding task of SSL/TLS encryption and decryption. This offloads the cryptographic workload from your Delphi application. It can be configured with the latest TLS versions (e.g., TLS 1.2, TLS 1.3), strongest cipher suites, and manage certificates from services like Let's Encrypt.
      * **Load Balancing:** If you have multiple instances of your WiRL service, the reverse proxy can distribute incoming requests across them, enhancing scalability and availability.
      * **Security:** It acts as the first line of defense, providing features like DDoS protection, WAF (Web Application Firewall) capabilities, request filtering, rate limiting, and IP whitelisting/blacklisting.
      * **Caching:** Can cache static content or even API responses to improve performance.
      * **Routing:** Directs requests to the correct internal WiRL service based on URL paths or hostnames.
3.  **Internal Communication (HTTP):** After the reverse proxy decrypts the request, it forwards it as a normal (and very speedy) **HTTP** request to your internal WiRL service.
4.  **WiRL Service:** Your WiRL service receives the plain HTTP request, processes it, and sends the HTTP response back to the reverse proxy.
5.  **Final Response:** The reverse proxy then encrypts the response and sends it back to the client over HTTPS.

This approach offers numerous benefits:

  * **Modern SSL/TLS:** Leverage the full capabilities of robust, constantly updated reverse proxy software for state-of-the-art encryption and security.
  * **Performance:** Offloads SSL overhead from your Delphi application, allowing it to focus on business logic. The internal HTTP connection is faster and requires fewer resources.
  * **Enhanced Security:** Provides an additional layer of defense against various web attacks.
  * **Scalability:** Facilitates load balancing and easier scaling of your backend WiRL services.
  * **Centralized Management:** Manage all your SSL certificates, security policies, and routing rules in one place.
  * **Simplified WiRL Development:** You don't need to concern yourself with complex SSL configurations directly within your Delphi application.

By adopting a reverse proxy deployment strategy, you ensure that your WiRL REST services are not only robust and high-performing but also secure and compliant with the latest web security standards.

![Reverse Proxy Deployment](../public/reverse-proxy.jpg){class=center-25 width=100%}
# WIRL - Chunked Encoding and SSE

WiRL supports SSE ([Server-Sent Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events)) and [chunked transfer encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Transfer-Encoding), which allows you to send a response divided into multiple blocks or chunks. This chapter explores both of these powerful features.

## SSE - Server-Sent Events

SSE (Server-Sent Events) is a specification that allows the server to send events to the client, something normally not possible with standard HTTP. What happens is that the client connects to a specific endpoint on the server and keeps the connection permanently open. Even in case of disconnection (due to network problems or other issues), the client must take care of restoring it as soon as possible.

![](./SSE.png){class=center-25 width=80%}

### Primary Use Cases

SSE (Server-Sent Events) is commonly used in several scenarios where real-time updates from server to client are essential. Common use cases include:

* Live dashboards and monitoring systems where data needs to be continuously updated without user intervention (e.g., stock tickers, sports scores, system metrics)
* Notification systems that alert users to new messages, alerts, or application events
* Collaborative applications where multiple users need to see changes made by others instantly
* IoT applications that require streaming sensor data or device status updates to web interfaces

The primary advantage of SSE over alternatives like WebSockets is its simplicity - it uses standard HTTP, requires minimal setup, and automatically handles reconnection. This makes SSE particularly suitable for one-way communication patterns where the server needs to push data to clients frequently but doesn't require complex bidirectional communication.

### Implementation

From WiRL's perspective, a resource that implements these events needs to be built following a specific pattern since it's not just about sending a simple object to the client. Let's first look at how to declare the method that will implement the resource:

```pascal
[GET]
[Produces(TMediaType.TEXT_EVENT_STREAM)]
function ServerSideEvents([QueryParam('tag')] const ATag: string): TWiRLSSEResponse;
```

The first thing to note is the `Produces` attribute with the value `TEXT_EVENT_STREAM`, as the SSE protocol uses a specific *Content-Type*. The HTTP method in this case is GET; you can use any HTTP method you like, but if the client is written in JavaScript, the standard API only supports GET. Then follows the parameters, which can be of any type, and finally the response type which has to be `TWiRLSSEResponse`.

Now let's look at the implementation:

```pascal
function TMyResource.ServerSideEvents(const ATag: string): TWiRLSSEResponse;
begin
  Result := TWiRLSSEResponse.Create(
    procedure (AWriter: IWiRLSSEResponseWriter)
    var
      LMessage: string;
    begin
      // Continue while the server is "alive"
      while FServer.Active do
      begin
        // Read a message from the queue
        LMessage := MessageQueue.PopItem;
        if LMessage <> '' then
          // If found, send it to the client
          AWriter.Write(LMessage);
      end;
    end
  );
end;
```

As you can see the `TWiRLSSEResponse` class has a constructor with only one argument. That's an anonymous method that will provide the events. The anonymous method continues as long as the server is "alive" (the `FServer` object can be retrieved via WiRL's Context Injection). In this example, the messages are in the `MessageQueue` object (defined as a thread-safe queue: `TThreadedQueue<string>`). The program attempts to extract a message from the queue and, if found, sends it to the client through the object referenced by the `IWiRLSSEResponseWriter` interface. Let's see the methods of this interface:

```pascal
procedure Write(const AValue: string);
```

This is the basic method for sending an event to the client. Note that the content of an event can only be a string. To send more complex objects, it's necessary to use some encoding, such as [Base64](https://developer.mozilla.org/en-US/docs/Glossary/Base64) for binary data.

```pascal
procedure Write(const AEvent, AValue: string);
```

This method is similar to the previous one but has the additional `event` parameter that allows "categorizing" the message. In fact, the JavaScript API allows the client to receive only messages belonging to a certain category.

```pascal
procedure Write(const AEvent, AValue: string; ARetry: Integer);
```

This version of `Write` has the additional `ARetry` parameter that tells the client how long to wait before opening a new connection once the current one is closed. Indeed, apart from network errors, the server could close the connection at any time.

```pascal
procedure WriteComment(const AValue: string);
```

This method sends a comment, which the client should generally ignore. Its main purpose is to keep the connection alive, as clients or proxies might close idle connections.

### The Client

Currently, WiRL doesn't offer a built-in way to read incoming events via SSE, although it is of course possible to use Indy components (`TIdHTTP`) or the new `THttpClient`.

If the client is a browser, you can use the `EventSource` object:

```javascript
const evtSource = new EventSource("/rest/app/myevent");

evtSource.onmessage = (event) => {
  console.log(event.data);
};
```

## Chunked Transfer Encoding

Another similar feature is support for chunked transfer encoding. This function allows sending data from server to client in blocks. This can be useful in several cases:

1. When the total size of the content is not known in advance, for example during dynamic generation of web pages or content.
2. For real-time data streaming, allowing the client to start processing data before it has been completely received.
3. To improve perceived response times, as the browser can start rendering parts of the page while others are still downloading.
4. In cases of large file transfers, where sending content in chunks may be more efficient than transmitting a single large block.

![](./chunked.png){class=center-25 width=80%}

### Implementation

Implementing a resource that uses chunked transfer encoding is not too different from the SSE case. In both cases, the resource produces a result gradually over time. Let's first look at the method interface that implements the resource:

```pascal
[GET]
[Produces(TMediaType.TEXT_PLAIN)]
function Chunks([QueryParam('chunks'), DefaultValue('5')] ANumOfChunks: Integer): TWiRLChunkedResponse;
```

In this case, the HTTP method is GET but it can be any method; the *Content-Type*, which the `Produces` attribute refers to, can also be any type, and it refers to the entire output of the resource, not the individual chunk. The parameters can clearly be of any type, while what distinguishes a chunked resource is the return type, which must be `TWiRLChunkedResponse`.

The implementation, as in the previous case, will have to provide the `TWiRLChunkedResponse` constructor with an anonymous procedure that will send individual chunks to the client:

```pascal
function TMyResource.Chunks(ANumOfChunks: Integer): TWiRLChunkedResponse;
begin
  Result := TWiRLChunkedResponse.Create(
    procedure (AWriter: IWiRLResponseWriter)
    var
      LCounter: Integer;
    begin
      // Send data in ANumOfChunks chunks
      for LCounter := 1 to ANumOfChunks do
      begin
        // Send a single chunk
        AWriter.Write(IntToStr(LCounter));
        // Simulate the wait required to get the next data
        Sleep(1000);
      end;
    end
  );
end;
```

In this example, the response is sent divided into different chunks determined by the client. Each chunk contains binary data. However, the object referenced by the `IWiRLResponseWriter` interface has several methods:

```pascal
procedure Write(const AValue: string; AEncoding: TEncoding = nil);
```

Allows sending a string by transforming it to binary with the specified encoding. In the absence of encoding, UTF-8 is used.

```pascal
procedure Write(const AValue: TBytes);
```

This method allows sending binary data directly using `TBytes`.

### Client

At the moment, `TWiRLClient` doesn't provide any special mechanism for reading data divided into chunks. The component will return the entire response once all chunks have been received. However, both the `TIdHTTP` component and `THttpClient` can handle incoming chunks in real-time via events. For example, you can use the `TIdHTTP` component in this way:

```pascal
procedure TForm1.ButtonIdHTTP1Click(Sender: TObject);
begin
  // Hook the OnChunkReceived event
  IdHTTP1.OnChunkReceived := IdHTTP1ChunkReceived;
  // Make the call
  IdHTTP1.Get('http://localhost:8080/rest/app/chunk');
end;

procedure TForm1.IdHTTP1ChunkReceived(Sender: TObject;
  var Chunk: TIdBytes);
var
  LText: string;
begin
  // Convert the chunk to string
  LText := IndyTextEncoding_UTF8.GetString(Chunk);
  // and add it to a memo
  MemoLog.Lines.Text := MemoLog.Lines.Text + LText;
end;
```

## Conclusion

In this chapter, we've provided an overview of using chunks and SSE with the latest version of WiRL. By downloading the source code from GitHub, you can test Demo *23.Chunks* which provides various examples of use. The current client support is somewhat limited, but future releases will offer improved features in the `TWiRLClient` component.