Package com.smartgwt.client.docs

# Interface ServerRestConnector

public interface ServerRestConnector

### Server-side REST Connector

NOTE: This article discusses Smart GWT's server-side REST client implementation. It should not be confused with the client-side `RestDataSource` implementation; the client-side dataSource is intended for cases where you are creating the server API and thus have control over the format and protocols used, but you do not wish to use the Smart GWT Server for some reason. The server-side implementation, which is documented below, is intended for cases where you need to connect to existing third-party REST APIs (which, despite the impression that "REST" is a standardized approach, vary significantly from one to the other in their details)

RestConnector is a built-in server-side `DataSource` implementation. It is able to convert a standard client-submitted or server-created `DSRequest` into an arbitrary REST webservice call, and convert the REST service response into a standard `DSResponse`. These conversions are highly configurable, making use of any or all of the following:

- `Record-level` and `field-level` XPath processing
- `Velocity-based` templates providing powerful declarative data templating and conversion for both `requests` and `responses`. These templates are evaluated at request/response execution time, so can include dynamic elements such as the criteria sent from the client
- Where declarative conversion is not sufficient, inline scripts written in Groovy, Javascript or other JSR-223 languages can add conversion of arbitrary complexity. Again, we support scripts for converting both `requests` and `responses` at the record-level, and for response data at the `field-level`

### Pervasive Velocity support

`RestController` was designed to be as flexible and configurable as possible. One of the ways we achieve this is with pervasive support for Velocity templating. In the descriptor (`*.ds.xml` file) of a RestController dataSource, you can use Velocity expressions in any element, and they will be replaced at execution time. This means that you can embed references to `server.properties` items, elements from the values and criteria of this operation, elements of other useful context objects, and arbitrary values that your code has set up in the Velocity template context (see the `Velocity overview` for details of these latter two). See the sample config below for examples of how this feature can be used. Additional examples are also shown in the docs of individual config properties (`headers`, for example)

Important: Because we allow references to `$criteria` and `$values` in `RestConnector` config, it follows that we re-evaluate Velocity expressions on every `DSRequest`; in fact, as the following section discusses, when there are multiple valueSets, we evaluate Velocity expressions multiple times per `DSRequest`. However, we do not evaluate `$config` references per-`DSRequest`: `$config` references are evaluated during `DataSource` initialization, and are fixed thereafter. The main implication of this is, if you are pooling and reusing `DataSource` instances (which is the default), `$config` references will be fixed after initial evaluation for the life of the JVM, so you should not expect to be able to change a config setting and have it picked up in `RestConnector` Velocity templates.

### Multiple ValueSets

`RestController` has a general ability to handle multiple valueSets, but only for REST services where both the `requestFormat` and the `responseFormat` are "json". For example, if we receive a `dsRequest` with two valueSets, like this:

         [
             {name:"Smith", ID:72},
             {name:"Jones", ID:1044}
         ]

We will combine those two records into a single JSON block to send to the remote REST server:

        [{"name":"Smith","ID": 72},{"name":"Jones","ID":1044}]

`RestConnector` is also able to wrap singular records in a list, for remote services that want to treat all input as a list - see `wrapInList`

`Request templates` are also able to handle multiple valueSets. If there are multiple valueSets in the `DSRequest`, or if `wrapInList` is in force, we will apply each valueSet to the template, constructing a list of templated JSON blocks to send to the REST server.

### Authentication

RestConnector provides the following standard authentication methods:

- Basic Authorization with a username and password or API token
- Bearer Authorization with an API token
- Bearer Authorization with a refresh/access token scheme, such as JSON Web Tokens (JWT)
- Manually-constructed Authorization header
- Ad-hoc, informal auth schemes, like embedding an API token in the body of the request

The supported authentication methods are all secure as long as you are using HTTPS connections, but the refresh/access token approach adds an additional layer of security by using frequently-changed, short-lived tokens instead of credentials that remain valid for an extended period. For this reason, we recommend using that approach if you have the choice.

As noted, `RestConnector` is flexible enough that it is able to connect with REST APIs that use non-standard authentication techniques, such as embedding a token or username/password credentials in the request body. These non-standard authentication approaches are found more often than might be thought, and although they are non-standard, they are not any less secure than the standard approaches as long as you are using HTTPS.

See the `auth block` documentation for full details.

### Example configuration

RestConnector configuration is typically expressed in the `serverConfig` block of a DataSource descriptor (`.ds.xml` file) - the client has no need to know about this configuration, and generally should not be able to see it - although `serverConfig` is optional in nearly every cases; see the `serverConfig` documentation for details of this.

An example configuration is shown below.

        <DataSource
            ID="SomeRestDataSource"
            serverType="rest"
        >
          <serverConfig>
            <requestFormat>params</requestFormat>
            <responseFormat>json</responseFormat>
            <recordXPath>items</recordXPath>

            <!-- This is the default URL to send REST requests to, if not overridden at the
                    OperationBinding level.  Note, this MUST be declared inside the serverConfig
                    block, otherwise client code in the browser will try to use it.  This example
                    just uses plain, untemplated config but there are lots more options - see the
                    operationBindings below -->
            <dataURL>https://somerestservice.com/api/search</dataURL>

            <auth>
              <type>basic</type>
              <username>$config['rest.somerestservice.apiUser']</username>
              <password>$config['rest.somerestservice.apiToken']</password>
            </auth>

            <operationBindings>
              <operationBinding operationType="fetch" operationId="customerFetch">
                <!-- You can use values defined in your server.properties file with the
                        "$config" context variable -->
                <dataURL>$config['rest.somerestservice.baseURL']/customers</dataURL>
              </operationBinding>

              <operationBinding operationType="update" operationId="updateCustomer">
                <!-- And you can use values and criteria sent up from the client with "$values"
                        and "$criteria" -->
                <dataURL>$config['rest.somerestservice.baseURL']/customer/$criteria['customerId']?name=$values['custName']</dataURL>
                <requestFormat>json</requestFormat>
              </operationBinding>

              <operationBinding operationType="remove">
                <!-- And you can use arbitrary values placed in the template context, as with
                        "$deletePath" here -->
                <dataURL>$config['rest.somerestservice.baseURL']/$deletePath/$values['itemKey']</dataURL>
              </operationBinding>
            </operationBindings>
          </serverConfig>
        </DataSource>

See Also:
  - `RESTRequestFormat`
  - `RESTResponseFormat`
  - `RESTAuthenticationType`
  - `com.smartgwt.client.data.RESTAuthentication`
  - `DataSource.serverConfig`
  - `DataSource.headers`
  - `OperationBinding.headers`
  - `DataSource.params`
  - `OperationBinding.params`
  - `DataSource.httpMethod`
  - `OperationBinding.httpMethod`
  - `DataSource.requestFormat`
  - `OperationBinding.requestFormat`
  - `DataSource.responseFormat`
  - `OperationBinding.responseFormat`
  - `DataSource.wrapInList`
  - `OperationBinding.wrapInList`
  - `DataSource.xmlTag`
  - `OperationBinding.xmlTag`
  - `DataSource.csvDelimiter`
  - `OperationBinding.csvDelimiter`
  - `DataSource.csvQuoteCharacter`
  - `OperationBinding.csvQuoteCharacter`
  - `DataSource.suppressAutoMappings`
  - `OperationBinding.suppressAutoMappings`
  - `DataSource.requestTemplate`
  - `OperationBinding.requestTemplate`
  - `DataSource.responseTemplate`
  - `OperationBinding.responseTemplate`
  - `DataSource.requiresCompleteRESTResponse`
  - `OperationBinding.requiresCompleteRESTResponse`
  - `DataSource.auth`
  - `RESTAuthentication.type`
  - `RESTAuthentication.username`
  - `RESTAuthentication.password`
  - `RESTAuthentication.authToken`
  - `RESTAuthentication.authHeader`
  - `RESTAuthentication.dataSource`