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, frompath 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.
the request
lang
parameter prioritizes the request languageif this parameter is not present, we use the language of the surfer's locale
if we still haven't determined a locale, we use the HTTP request locale (header
Accepted-Language
)if we still haven't determined a locale, we use the system's default locale
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
check whether the
debug
parameter is present or not in the requestdetermine whether the surfer has the right to use this parameterand to what type of information it has access
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.
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 actionotherwise, 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 theonWorkflow_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 :
a psql query
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
parameterthe 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 creationtriggersAppliedOnUpdate
for the application of triggers on a modificationtriggersAppliedOnPartialUpdate
for applying triggers to a partial modification (patch
)triggersAppliedOnAssign
for applying triggers to an assignmenttriggersAppliedOnWorkflow
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:
rest_api_trigger_parameter
forallowOverrideTriggersApplication
totrue
rest_api_disable_trigger_on_create
fortriggersAppliedOnCreate
tofalse
rest_api_disable_trigger_on_update
fortriggersAppliedOnUpdate
tofalse
rest_api_disable_trigger_on_partial_update
fortriggersAppliedOnPartialUpdate
tofalse
rest_api_disable_trigger_on_workflow
fortriggersAppliedOnWorkflow
tofalse
rest_api_eval_workflow
(see API operation - Interaction with components | Cas spécial des workflows )
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
(implementscom.noheto.extensions.interfaces.services.IObjectTriggerBusinessService
)com.noheto.extensions.interfaces.services.AbstractWorkflowTriggerBusinessService
(implementscom.noheto.extensions.interfaces.services.IWorkflowTriggerBusinessService
)
Business Services API
The API also offers its own triggers (API Business Services):
com.noheto.restapi.APIBusinessServiceAdapter
(implementscom.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 servicescreateOrUpdateTrigger
for RESTful services
or, by contribution, through the extension
com.noheto.restapi.DamContributionAdapter
(implementscom.noheto.restapi.IDamContribution
) forcreateOrUpdateTrigger
(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.