API operation - Interaction with components

This documentation describes how the services executed by the WXM_RESTAPI plusing interact with different processes and components.

In general, we can distinguish different cases of end points:

  • READ end points, which allow you to obtain an instance

  • end points of the LIST or TREE type, which can be used to obtain several instances in a list or tree format

  • end points

    • for creation (CREATE)

    • for modification (UPDATE)

    • for deletion (DELETE)

  • othets

    • aggregates

    • status change (workflow)

    • workcopy

    • whoami

    • notification

Services of the same type are generally based on the same code and therefore operate according to the same general rules (in particular, however, the result may be different depending on the configuration).

End points Sets

End points are organized into sets of end points that operate in a similar way or relate to the same functionality, with each set configured according to its own rules, while all end points within the same set follow the same configuration guidelines.

Please note. Operation may differ from general operation in certain special cases. See special cases.

DAM services

These are RESTful services, where each end point concerns a resource (usually an object in the database), and the action is selected

  • mainly via the HTTP method

  • sometimes by a part of the path at the end of the URI

DAM services are configured automatically

  • based on automation rules

  • from tags on object structures and fields

Configuration may be overridden by hard-coded configuration (JSON). Sometimes the configuration is determined by the code and cannot be modified, or can only be partially modified.

DATA services

DATA services operate like DAM services, but their configuration is essentially defined by a JSON file for the resource. An option can be used to automatically configure properties in a similar way to DAM services.

PROFIL service

The PROFILE service operates like a DAM service, but its configuration is largely hard-coded. Some properties can be configured automatically. Its endpoints only concern the “user modifies himself” functionality.

MASSIMPORT (or BULKUPLOAD) services

MASSIMPORT services operate in part like DAM services, but there are major differences in the way certain end points operate, and in particular in the way the surfer is processed.

APPSETTINGS services

These services operate in the same way as DAM services.

Others

There are many other services. This documentation does not deal specifically with them.

Signin services, signout, refresh...

Notification services

Connection configuration

Importing list metadata

Security testing services

Ping service

Documentation services

Search services

Pass through

Preset services

Scripting services

Other services

There are other services, some of which are simply redirections to legacy services.

Whoami

User preferences

Configuration (API and server)

Status service

Legacy services

This is the first version of REST APIs. These services are not RESTful: each end point corresponds to an action. The overall operation is similar to that of DAM services, but not all DAM service evolutions have been implemented in legacy services.

These are services whose URI begins with /api/json/ or /api/media/.

Processes and components

There are small differences in the various interactions between these end points and the different processes, which will be specified as required. Generally speaking, however, the various processes and components in question are :

  • determine request context

    • surfer

    • locale

    • filters (SQL queries, fulltext queries, etc.)

    • various other context variables

      • debug mode

  • routing
    this process consists of determining which sub-component will be executed to resolve the API request, from

    • path in URL

    • HTTP method

    • parameters and configuration

  • determine rights

    • to invoke the end point

    • execute actions on the object instances concerned

  • determine base wheres

  • determine the properties to be loaded for each instance

  • execute facets

    • for exhibition (property rights)

    • to filter exposed properties

  • execute triggers

  • specific parameters (fulltext, SQL filters, order by...)

  • locks

Please note. Operation may differ from general operation in certain special cases. See special cases.

General process

Request context

From the outset, there is a pre-route that determines the set of services, and then the context is built. The context is initialized to allow the earliest possible rejection:

  • supported authentication methods

  • supported HTTP methods

Determining the surfer

The surfer is obtained via the request (CTSurfer.from(request)). In the event of non-presence, additional API mechanisms rely on the JWT token (or Cookie x-wedia-api-token) or the Bearer to restore a surfer.

Please note. Operation may differ from general operation in certain special cases. See special cases.

Determining the user langage

The request language is determined by a particular process and is not necessarily the language of the surfer's locale.

  1. the request lang parameter prioritizes the request language

  2. if this parameter is not present, we use the language of the surfer's locale

  3. if we still haven't determined a locale, we use the HTTP request locale (header Accepted-Language)

  4. if we still haven't determined a locale, we use the system's default locale

  5. if we still haven't determined a locale, we use Locale.US

Determining the debug mode

To determine whether the request is in debug mode, we

  1. check whether the debug parameter is present or not in the request

  2. determine whether the surfer has the right to use this parameterand to what type of information it has access

  3. if no parameter, we use the default value

Routing

Once the context of the request has been determined, the URI path is decomposed and used, in combination with the HTTP method, to identify several elements:

  • The component (as well as this component's method) that will be used to run the service,

  • The type of resource concerned by the service and therefore the service configuration,

  • The resource identifier, if the request targets a specific resource,

  • For some services, when the URI path includes the name of a property, the specific field on which the operation will be performed.

Determine invocation rights

Once the component, method and parameters have been determined, we test whether the surfer has the right to invoke the service.

  1. if the RESTAPI domain exists and is activated, we test whether the user has the right to invoke the end point via this domain and the corresponding action

  2. otherwise, everyone has the right to invoke any service

Define execution rights

Execution rights management is handled by the engine's wsnoheto.securite.SecurityManager (or by the engine APIs that use it), depending on endpoint type and configuration.

View rights are generally evaluated implicitly by the engine components used to make queries. (wsnoheto.engine.TopSearch, wsnoheto.engine.CTObjectsIterable…).

In the case of queries for modifications, deletions, creations and workflow changes, a preliminary test is carried out before processing begins, to determine as soon as possible whether the action should be refused or accepted. Next, the implicit tests of the wsnoheto.IObjectWritable.JSPSave() method are applied when this method is invoked.

Special case of workflows

To evaluate possible state change actions, taking rights into account, we use the formula action.getCondition().test(surfer, workflow, action) where

  • surfer is the surfer (wsnoheto.engine.CTSurfer)

  • workflow is the workflow of the object (noheto.workflow.IWorkflow)

  • action is the action to be tested (noheto.workflow.IAction)

If the action is possible according to this formula, then we test the query parameter evalWorkflows :

  • if evalWorkflows is true, we determine whether the action is possible according to workflow triggers (com.noheto.extensions.interfaces.services.IWorkflowTriggerBusinessService) by invoking the onWorkflow_beforeEvaluate(surfer, workflow, action) method.

  • if evalWorkflows is false, the action is considered possible

The default value of this parameter is set by the workflowTriggerFilterApplied configuration property (default is false and can be set to true via the rest_api_eval_workflow structure tag).

Determing base wheres

Base wheres are SQL filters. They are determined by

  • engine components(com.noheto.preparedwhere.PreparedWhereService)

  • API Business services

    • com.noheto.restapi.RESTAPIBaseWhereBusinessService

    • com.noheto.restapi.DependencyBaseWhereBusinessService

    • com.noheto.restapi.AggBaseWhereBusinessService

  • configuration

    • base wheres mappings

    • base wheres id

They are determined by the query context:

  • surfer

  • request

  • resource

  • type of end point

Determining query

The final query (or queries, in the case of multiple object types) is a combination (by and) of different queries:

  • queries specified in the configuration

  • queries based on parameters

  • base wheres

  • static queries

Queries specified in configuration

JSON configurations allow you to specify :

  1. a psql query

  2. a parameterized json query
    A query whose values can be dynamic parameters (such as a surfer property, for example).

Configurations generated automatically by tag cannot have a configured query (especially DAM services). You need to use a JSON configuration for this.

Queries based on parameters

Standard parameter

The standard filtering SQL query for a resource type is set by the query parameter. The syntax is called JSON-Query.

Multiple resources

If the end point selects several resource types, the query in the query parameter applies to all objects. For queries specific to each resource type, we use a parameter named query followed by an underscore and the name of the resource (for example, query_asset).

Trees

In the case of trees, the query applies to all resources. In the case of a tree using the READ service and the depth parameter, there is a rootQuery parameter to indicate a query that will only apply to the root of the tree. This parameter has no effect in the case of the /api/tree service. This parameter is declinable by resource type, as is the query parameter.

Static queries

Hard-coded queries can be used to determine the search filter.

Working copy versions

By default, the search query includes a clause that excludes non-active versions. This clause can be deactivated using the queryVersions parameter.

READ or equivalent services

In such a service, the URI provides the identifier (or UUID) of the desired resource. A query of type pid={id} is created to be used (combined with the other clauses) in the same way as a query of parameter query.

This is also the case, for example, with /api/rest/dam/asset/<nature> services.

Determining the properties to be loaded

In general, for READ and LIST services, only the properties required to establish the response to the API are loaded. However, it is often necessary to load other properties, either for the establishment of additional technical properties, or for security tests or facet calculations, etc. The properties to be loaded for each object are therefore determined by

  • the properties specified in the configuration

  • the properties indicated in the request's props parameter

  • properties known to be necessary for the evaluation of certain technical properties, where applicable

  • properties known to be necessary for the exposure of certain properties according to the techprops parameter

  • the need to evaluate security or facets, or the need to modify or delete an object (in which case all properties are loaded)

  • mechanisms for extension components (API Business Services), such as custom sections

Executing facets

Facets are evaluated with the request surfer.

API request variables

The API also passes specific variables:

  • dam_rest_api_service: service name (e.g. DAM_READ)

  • dam_rest_api_endpoint: a type of end point (e.g. READ)

  • dam_rest_api_service_type: a type of service (e.g. DAM)

Executing triggers

Triggers are executed using the request surfer as part of the implicit execution when a wsnoheto.IObjectWritable.JSPSave() is used, for example. It is possible to control the execution of triggers through service configuration, for modification or creation, and workflow status change in RESTful services (legacy services don't have this capability).

Through JSON configuration

By default, triggers are always applied, but the following configuration properties can be used to disable the application of triggers to the resource, if set to true :

  • triggersAppliedOnCreate for applying triggers to a creation

  • triggersAppliedOnUpdate for the application of triggers on a modification

  • triggersAppliedOnPartialUpdate for applying triggers to a partial modification (patch)

  • triggersAppliedOnAssign for applying triggers to an assignment

  • triggersAppliedOnWorkflow for applying triggers on a change in workflow status

It is also possible to disable triggers and allow them to be executed by the invocation using the allowOverrideTriggersApplication property: however, it is not possible to do this on one type of trigger and not another.

Through automatic configuration (tags)

For automatic configuration, the following tags (on structure) can be used to apply the properties mentioned in the previous paragraph:

By request

When the user is authorized to request the execution of triggers, he can use the applyTriggers= true parameter to request the execution of triggers.

Engine

In standard cases, when the configuration requests the execution of triggers, the motor triggers are executed with the context surfer. As a reminder, these are

  • com.noheto.extensions.interfaces.services.AbstractObjectTriggerBusinessService (implements com.noheto.extensions.interfaces.services.IObjectTriggerBusinessService)

  • com.noheto.extensions.interfaces.services.AbstractWorkflowTriggerBusinessService (implements com.noheto.extensions.interfaces.services.IWorkflowTriggerBusinessService)

Business Services API

The API also offers its own triggers (API Business Services):

  • com.noheto.restapi.APIBusinessServiceAdapter (implements com.noheto.restapi.RESTAPIBusinessService)

To operate, the component must be associated with the resource :

  • through JSON configuration (by specifying a plugin name (pluginname) and a class name (classname))

    • updateOrModifyTrigger for legacy services

    • createOrUpdateTrigger for RESTful services

  • or, by contribution, through the extension com.noheto.restapi.DamContributionAdapter (implements com.noheto.restapi.IDamContribution) for createOrUpdateTrigger (it doesn't work for legacy services)

Locks

Modification APIs manage mutual exclusion locks to ensure that two simultaneous modification requests on the same object instance (even if it's the same surfer) don't run at the same time, but successively. Once this lock has been obtained, a conventional lock (object engine lock) is set on the object instance to prevent simultaneous object modifications by two different users.

Writing the response

In DAM services, the production of the response

  • in the case of a READ service depends on the configuration and request parameters

  • in the case of a LIST service, corresponds to a list of objects whose form is identical to that obtained by a READ service

  • in the case of a create, modify or delete service, the response is constructed according to the same rules as a READ service, possibly with additional information

In legacy services, response generation depends on the action performed and its configuration.

Special cases

Massimport/Bulkupload & Creative workflows

The mass import and creative workflow functions are based on the same componants, but work differently.

This applies in particular to the massimportjob and massimportitem objects, and especially to the collections objects (i.e. dam objects) used during simulation production (which has a particular impact on the operation of indexing in the upload and creative workflow on the front end).

Asynchronous operation

Asset indexing property values, as part of the upload and creative workflow processes, are transmitted to the server in the form of commands via the job modification API (represented by a massimportjob instance, which corresponds either to an upload batch, or to a job linked to the creative workflow space). Each command specifies various operations (property modification, publication, choice of target asset type, status change, etc.) for one or more massimportitem instances. This command modifies and saves the massimportjob instance, in the same way as any modification via the API. The massimportjob instance is then sent to an asynchronous execution system, which distributes the modifications to each massimportitem. Some modifications are applied directly to the massimportitem fields, while others are stored in a JSON object (stored in a property of massimportitem). During this process, aggregate properties are also calculated (see below), as is the simulation of operations.

Triggers

When a massimportitem instance is modified, recalculation of the aggregate properties and simulation becomes necessary. As a result, the task normally performed by the asynchronous execution system after the massimportitem instance has been updated is also executed at that time by trigger.

Simulation

When querying the state of a massimportitem, it is necessary to know what state the final asset would take if the massimportitem were published. This includes:

  • indexing properties stored in JSON,

  • properties directly recorded in the massimportitem,

  • the facets required to generate the indexing form,

  • aggregation properties,

    • an indication of the asset's validity (or at least its current level of completion),

    • a mechanism for performing full-text searches on JSON.

This state is called "simulation" and is recalculated on demand, either during an asynchronous operation, or following the execution of a modification trigger on the massimportitem. The simulation can then be saved as a cache in a massimportitem property.

It should also be noted that certain properties generated by the simulation may be copied into the massimportitem following this recalculation.

Determining the surfer

Given that simulation and the properties dependent on it (such as aggregation properties) can be calculated in different contexts (API request, asynchronous processing, trigger, etc.), for which there is not always an associated request, and to simplify rights management (in particular the application of security rules), the user used to process the simulation, save the results in the massimportitem instance and eventually publish the asset in the DAM, is not necessarily the request surfer, but a virtual surfer created from the job owner. This virtual user's connection is initialized via Surfer Services, without any interaction with an HTTP request.

Within the upload framework, in its current form (without aggregation properties and with the job owner as the only interactive user), a mechanism guarantees that the user used for calculation, simulation and publication operations is indeed the request user, provided that it is the job owner. In this case, it can be assumed that there are interactions with the HTTP request. In particular, this makes it possible to determine certain properties linked to the user via the active session when calculating facets.