REST API - DDSA Service Evaluation
You can execute DDSA Service Requests via the /api/v1 endpoint.
On this page
Overview
| Supported Method | Description | 
|---|---|
| GET | Used for simple DDSA service requests. All properties are encoded in the URL parameters or as custom (so starting with gm-) headers. The properties must be of typeString,int,float,long,double,boolean,Date,decimal,enumor a list or set of the mentioned types. | 
| POST | Used for more complex DDSA service requests. All types are supported. The service request can either be provided as form data or encoded in the body of the request, with the mimeTypeprovided in theContent-Typeheader. | 
| PATCH | Used in the same manner as POST. | 
Every service request call is unmarshalled into the following entities:
- the actual call
- the endpoint, which contains multiple properties that drive the behavior of the endpoint, independently of the actual service requests you want execute.
The properties of the ServiceRequest may be prefixed with service and properties of the Endpoint entity may be prefixed with endpoint.
If no prefix is provided, we'll try to find the property in the service request first, then in the endpoint. If the property doesn't exist anywhere, we'll send a 400: Bad request error with an error message.
For more information, see REST Parameters and Headers.
Service Domain
A service domain serves a similar purpose as a namespace, in the sense that it groups certain elements according to some arbitrary criteria. In our context, the elements are service requests and the criterion has to do with the where the service is evaluated.
The idea is that you can have the same request handled in different ways in different domains. Another reason is that you want to keep unrelated things separated, so only requests that logically belong together can be found in the same service domain.
An instance of the ServiceDomain type you create manually must have a service model assigned. After all, service domains group service requests and those come from service models. Depending on the implementation and logic of the service processors used in service requests of a service model, service requests grouped in one service domain can optionally have their results persisted. Moreover, a service model can depend on one or more other service models that represent specific business models for a wide range of concrete operational needs.
A standard access is also a service domain, as it groups the entire functionality of what you can do with the entities of its assigned metamodel within the access. Note that your access does not have to have a service model to be considered a service domain. Out-of-the-box, you can use CRUD operations on the entities assigned to the metamodel of an access as CRUD operations are automatically exposed as REST API when deploy an access that has a metamodel assigned.
The serviceDomain part of the URL is necessary for every API call, as it specifies where the service is located, which is usually an access. You can, however, have a service domain which is not an access.
You can create a new service domain in Control Center by looking up ServiceDomain using the Quick Access bar and creating a new instance.
Service domain is a parameter which must be specified in the path of every service request REST call. If you don't specify it, you will send your call to the default domain.
Overriding Service Domain
You can override the service domain by passing a serviceDomain parameter in the URL of the call or by providing a domainId in the body of the call. This is useful when you want to run a service request from one domain on another one. The best example for this is the GMQL REST call.
The GMQL REST call is a part of the default serviceDomain:default service domain. If you want to run a GMQL query on another domain (access), you must override the service domain by adding serviceDomain=yourServiceDomain to the URL or by adding domainId="yourServiceAccess" to the body, for example, calling host:port/tribefire-services/api/v1/gmql?statement=from%20com.braintribe.model.generic.GenericEntity&domainId=myCustomAccess will send the GMQL query from com.braintribe.model.generic.GenericEntity to the access with the external ID myCustomAccess.
Simple Name Resolution
If your service request has a simple name that is unique within a given service domain, then instead of using the /api/v1/serviceDomain/foo.bar.ExampleServiceRequest notation you can just use /api/v1/serviceDomain/ExampleServiceRequest. If the simple name is not unique and you try to use the /api/v1/serviceDomain/ExampleServiceRequest notation, you will get an exception.
Authentication
Send a POST call to /api/v1/authenticate for authentication. Make sure to provide your credentials in the body of the request:
| Item | Description | 
|---|---|
| Method and Link | POST host:port/tribefire-services/api/v1/authenticate | 
| Body | { "user": "cortex", "password": "cortex" } | 
| Headers | Content-Type: application/json | 
You have to include the session ID in every REST call. You can include it in the following:
- URL parameter: sessionId=yourSessionId
- header parameter: gm-session-id
You cannot include the session ID in the body of the request!
If you are not logged in (there is no valid session) and you paste a GET call in your browser, you will be redirected to a login screen. After logging in, you will see the result
of your GET call.
The redirect does not happen for the
/api/v1/authenticatecall.
Endpoint Configuration
You can configure the behavior of the REST endpoint by assigning desired values to available parameters:
- Write Empty Properties
- Stabilize Order
- Prettiness
- Projection
- Depth
- Entity Recurrence Depth
- Type Explicitness
- Identity Management Mode
- Download Resource
- Save Locally
- Response Filename
- Response Content Type
Write Empty Properties
| Parameter | Description | 
|---|---|
| URL Parameter | write-empty-properties=<...> | 
| Header Parameter | gm-write-empty-properties=<...> | 
| Type | Boolean | 
| Default Value | false | 
| Description | When this flag is set to true, the marshaller returns all properties that are set tonullor are empty (for maps, sets and lists) | 
Stabilize Order
| Parameter | Description | 
|---|---|
| URL Parameter | stabilize-order=<...> | 
| Header Parameter | gm-stabilize-order=<...> | 
| Type | Boolean | 
| Default Value | false | 
| Description | When this flag is set to true, the marshaller ensures that properties in different instances of the same entity are always in the same order. This is especially useful when you return empty properties using thewriteEmptyPropertiesparameter. | 
Prettiness
| Parameter | Description | 
|---|---|
| URL Parameter | prettiness=<...> | 
| Header Parameter | gm-prettiness=<...> | 
| Type | none,low,midorhigh | 
| Default Value | mid | 
| Description | This property represents the level of prettiness used when writing the assembly back to the body of the response. Each implementation of the marshaller may use this value slightly differently, but as a rule of thumb, nonecontains no new lines or indentation information and should only be used to minimise the size of the body andhighprovides the best possible indentation for humans to read. | 
Projection
| Parameter | Description | 
|---|---|
| URL Parameter | projection=<...> | 
| Header Parameter | gm-projection=<...> | 
| Type | String | 
| Default Value | null | 
| Description | When the response to a call is a GenericEntity(i.e. in most of the cases), this value represents the path of properties to be returned from the response. | 
In this example, the following REST call: /api/v1/serviceDomain/foo.bar.ExampleServiceRequest
returns the following answer (encoded as JSON) without projection:
{
  "_type": "foo.bar.ExampleServiceResponse",
  "exampleProperty": {
    "_type": "foo.bar.ExampleEntity",
    "anotherProperty": {
      "_type": "foo.bar.AnotherEntity",
      "stringValue": "Welcome to tribefire documentation!"
    }
  },
  "intValue": 42,
  "someList": [0, 1, 5]
}
The following are different values returned for various projections:
- projection=intValue
42
- projection=exampleProperty
{
   "_type": "foo.bar.ExampleEntity",
   "anotherProperty": {
      "_type": "foo.bar.AnotherEntity",
      "stringValue": "Welcome to tribefire documentation!"
   }
}
- projection=exampleProperty.anotherProperty.stringValue
"Welcome to tribefire documentation!"
The following projections are not supported:
- projection=_type: the projection should be a list of property names separated by- .and- _typeis not a property, but an internal value added by tribefire used when unmarshalling a JSON
- projection=someList.0: it is not possible to reference values inside of collections
Depth
| Parameter | Description | 
|---|---|
| URL Parameter | depth=<...> | 
| Header Parameter | gm-depth=<...> | 
| Type | shallow- returns only the first levelreachable- returns the whole assemblynumber >= 0- returns the provided level, starting at0 | 
| Default Value | 3 | 
| Description | For complex assemblies, this property specifies how deep the returned assembly should be traversed before being returned. This property is a simplified TraversingCriterion. | 
The depth parameter is applied after the projection parameter.
In this example, the following REST call: /api/v1/serviceDomain/foo.bar.ExampleServiceRequest
returns the following answer (encoded as JSON, with writeEmptyProperties=true) without the projection parameter set:
{
  "_type": "foo.bar.ExampleServiceResponse",
  "a": {
    "_type": "foo.bar.EntityA",
    "b": {
      "_type": "foo.bar.EntityB",
      "c": {
        "_type": "foo.bar.EntityC",
        "d": {
          "_type": "foo.bar.EntityD",
          "e": "We need to go deeper."
        }
      }
    }
  }
}
The following are different values returned for various depths:
- depth=shallow: only returns the first level
- depth=0: only returns the first level
{
  "_type": "foo.bar.ExampleServiceResponse",
  "a": null
}
- depth=2: returns the 3 first levels (zero-indexing)
{
  "_type": "foo.bar.ExampleServiceResponse",
  "a": {
    "_type": "foo.bar.EntityA",
    "b": {
      "_type": "foo.bar.EntityB",
      "c": null
    }
  }
}
- depth=reachable: returns the entire assembly
- depth=327: any number bigger than the maximum depth returns the entire assembly
{
  "_type": "foo.bar.ExampleServiceResponse",
  "a": {
    "_type": "foo.bar.EntityA",
    "b": {
      "_type": "foo.bar.EntityB",
      "c": {
        "_type": "foo.bar.EntityC",
        "d": {
          "_type": "foo.bar.EntityD",
          "e": "We need to go deeper."
        }
      }
    }
  }
- depth=1&projection=a.b: starting from- foo.bar.EntityB, returns 2 levels (starting at 0...)
{
  "_type": "foo.bar.EntityB",
  "c": {
    "_type": "foo.bar.EntityC",
    "d": null
  }
}
Entity Recurrence Depth
| Parameter | Description | 
|---|---|
| URL Parameter | entity-recurrence-depth=<...> | 
| Header Parameter | gm-entity-recurrence-depth=<...> | 
| Type | number >= -1- returns the provided level, starting at0 | 
| Default Value | 0 | 
| Description | For complex entities which have recurrent entities (entities that appear more than once in the returned JSON), this property specifies how deep the returned recurrent entity should be traversed before being returned. This property is used to avoid _idand_refin the returned JSON. | 
The entity-recurrence-depth parameter is applied after the depth parameter.
In this example, the following REST call: /api/v1/serviceDomain/foo.bar.ExampleServiceRequest without the projection parameter set returns the following answer (encoded as JSON, with write-empty-properties=true) :
{
  "_type": "foo.bar.ExampleServiceResponse", "_id": "0",
  "a": {
    "_type": "foo.bar.EntityA", "_id": "1",
    "b": {
      "_type": "foo.bar.EntityB", "_id": "2",
      "name": "name_of_entity_B",
      "c": {
        "_type": "foo.bar.EntityC", "_id": "3",
        "d": {
          "_ref": "2"
        }
      }
    }
  }
}
Note there are different values returned for various settings of entity-recurrence-depth:
- entity-recurrence-depth=0: returns marshalled JSON with- _idand- _ref
{
  "_type": "foo.bar.ExampleServiceResponse", "_id": "0",
  "a": {
    "_type": "foo.bar.EntityA", "_id": "1",
    "b": {
      "_type": "foo.bar.EntityB", "_id": "2",
      "name": "name_of_entity_B",
      "c": {
        "_type": "foo.bar.EntityC", "_id": "3",
        "d": {
          "_ref": "2"
        }
      }
    }
  }
}
- entity-recurrence-depth=1: only returns first level (scalar values) for the recurrent entity
{
  "_type": "foo.bar.ExampleServiceResponse",
  "a": {
    "_type": "foo.bar.EntityA", "_id": "1",
    "b": {
      "_type": "foo.bar.EntityB", "_id": "2",
      "name": "name_of_entity_B",
      "c": {
        "_type": "foo.bar.EntityC", "_id": "3",
        "d": {
          "_type": "foo.bar.EntityB",
          "name": "name_of_entity_B"
        }
      }
    }
  }
}
- entity-recurrence-depth=-1: returns the entire recurrent entity (an entity that appears more than once in the returned JSON), if cyclic dependency is detected it will only return scalar values for that entity.
Write Absence Information
| Parameter | Description | 
|---|---|
| URL Parameter | write-absence-information=<...> | 
| Header Parameter | gm-write-absence-information=<...> | 
| Type | Boolean | 
| Default Value | false | 
| Description | When this Boolean flag is set to true, the marshaller writes information for all absent properties. | 
Type Explicitness
| Parameter | Description | 
|---|---|
| URL Parameter | type-explicitness=<...> | 
| Header Parameter | gm-type-explicitness=<...> | 
| Type | auto,always,entitiesorpolymorphic | 
| Default Value | auto | 
| Description | This property is used to decide whether _typeis present in marshalled JSON.This property is only available in JSON marshaller. auto - _typeis always returned for entity types and properties that are not known simple types (String, integer, etc).always - _typeis always returned for every elemententities - _typeis always returned for entity types and properties that are not known simple types (String, integer, etc).polymorphic - _typeis returned for every element if the actual type cannot be established from the context | 
Identity Management Mode
| Parameter | Description | 
|---|---|
| URL Parameter | identity-management-mode=<...> | 
| Header Parameter | gm-identity-management-mode=<...> | 
| Type | off,auto,_idorid | 
| Default Value | auto | 
| Description | Represents how duplicates of objects should be unmarshalled. auto - Depending on the parsed assembly, the marshaller automatically detects the identification information and uses it for identity management. off - No identity management. _id - The internally generated _idinformation is used, if available.id - The idproperty is used, if available. | 
Download Resource
| Parameter | Description | 
|---|---|
| URL Parameter | download-resource=<...> | 
| Header Parameter | gm-download-resource=<...> | 
| Type | Boolean | 
| Default Value | false | 
| Description | When set to true, the result of the request is not the JSON representation of the Resource but the binary data itself. | 
Save Locally
| Parameter | Description | 
|---|---|
| URL Parameter | save-locally=<...> | 
| Header Parameter | gm-save-locally=<...> | 
| Type | Boolean | 
| Default Value | false | 
| Description | When set to true, the Resource being handled by the request is not displayed in the browser (if the Resource is of type understood by the browser) but is downloaded (thecontentDispositionheader changes frominlinetoattachment). For more information about this header, see developer.mozilla.org. | 
Response Filename
| Parameter | Description | 
|---|---|
| URL Parameter | response-filename=<...> | 
| Header Parameter | gm-response-filename=<...> | 
| Type | String | 
| Default Value | n/a | 
| Description | Represents the filenameof the file downloaded (changes the value of thefilenameproperty of thecontentDispositionheader). For more information about this header, see developer.mozilla.org. | 
Response Content Type
| Parameter | Description | 
|---|---|
| URL Parameter | response-content-type=<...> | 
| Header Parameter | gm-response-content=type=<...> | 
| Type | MIME Type String | 
| Default Value | n/a | 
| Description | Sets the MIME type of the content. | 
GET
The GET service request call URL is formed according to the following pattern:
/api/v1/serviceDomain/type.signature.of.ServiceRequest
You can use the URL and the header parameters to populate the ServiceRequest and the Endpoint entities.
The GET method does not support passing in a body, therefore all the properties of the ServiceRequest as well as Endpoint entities must be fully set from the URL and header parameters. You can work with all property types, but some of them will require using an alias first - see Complex Request Properties.
Examples:
Method: GET
URL: http://localhost:8080/tribefire-services/api/v1/serviceDomain/com.braintribe.model.securityservice.GetCurrentUser?sessionId=session-id
Headers:
- Accept:- application/json
- Content-Type:- application/json
Response:
{
  "_type": "com.braintribe.model.user.User",
  "id": "some-id",
  "firstName": "cortex",
  "lastName": "cortex"
}
Here are several examples of the same call which returns the current user session from a sessionId but written in different forms:
- 
All parameters in URL, without prefix URL: /api/v1/serviceDomain/com.braintribe.model.securityservice.GetCurrentUser?sessionId=xxx&prettiness=high
 Headers:- Accept:- application/json
 
- 
All parameters in URL, with prefix URL: /api/v1/serviceDomain/com.braintribe.model.securityservice.GetCurrentUser?service.sessionId=xxx&endpoint.prettiness=high
 Headers:- Accept:- application/json
 
- 
All parameters in headers, without prefix URL: /api/v1/serviceDomain/com.braintribe.model.securityservice.GetCurrentUserHeaders:
- 
Accept:application/json
- 
gm-session-id:xxx
- 
gm-prettiness:high
- 
All parameters in headers, with prefix: URL: /api/v1/serviceDomain/com.braintribe.model.securityservice.GetCurrentUser
 Headers:- Accept:- application/json
- gm-service.session-id:- xxx
- gm-endpoint.prettiness:- high
 
- 
Parameters mixed between headers and URL parameters, without prefix: 
URL: /api/v1/serviceDomain/com.braintribe.model.securityservice.GetCurrentUser?sessionId=xxx
Headers:
- Accept:- application/json
- gm-prettiness:- high
Complex Request Properties
Above you learned about how to set simple request properties. However, if you want set values on complex property types in your request (such as entities, maps, collections of entities, properties of the object type), you will need to use an alias.
Let's imagine a GET request to find movies:
FindMoviesRequest which returns a response of Type List<Movie>.
Our request has the following properties (indention indicates properties set on other properties (sub-properties); the type of a property follows behind its name):
- name (String)
- director (Entity Director)
 - name (String)
 - country (String)
 - awardsWon (Entity AwardsWon)
   - institution (Entity Institution)
     - name (String)
   - name (String)
- category (List<CategoryEnum>) (CategoryEnum's constants: Horror, Romance, Thriller, Comedy)
- additional (Map<String,String>)
  [Example:
    key: wonOscar
    value: true]
Example 1 - Simple Entities
As first example, let's try to find all movies of Austrian directors.
Let director property have the alias d. This is expressed using the following syntax: director=@d, which we will use to set the sub-properties of the director request property. In our example it's the country:
@d.country=Austria
Note that you couldn't just say director.country=Austria, because that would mean that director is expected to be an alias which must have been introduced by you first - as demonstrated in the previous paragraph.
On the right side of the equal sign, the same rules apply as if it would be a "normal" request property. In this example: Because the Director's country property is of type String, the property can be set directly, as demonstrated.
The final URL then looks as follows:
findMovies?director=@d&d.country=Austria
Example 2 - Deeply Nested Entities
Now, we will try to set the name of the award won by the director to oscar. In this situation, name is a property of awardsWon, and awardsWon is a property of director:
- director (Entity Director)
 - name (String)
 - country (String)
 - awardsWon (Entity AwardsWon)
   - institution (Entity Institution)
     - name (String)
   - name (String)
First, we need to set an alias for director:
director=@d
Then, we need another alias for awardsWon:
@d.awardsWon=@a
Only now can we reach name:
a.name=oscar
Combining the above into a single request, we get:
findMovies?director=@d&d.awardsWon=@a&a.name=oscar
Example 3 - Collections
Let's try to set the movie category to romance and horror (who doesn't enjoy some sparkling vampires every now and then).
Now, we can assign enum values in our request:
category=horror&category=romance
Combining the above into a single request, we get:
findMovies?category=horror&category=romance
Example 4 - Maps
The property additional has the type map. We use an alias a to add another entry to the map. Note that the alias does not refer to the map but to a map entry: additional=@a.
We can set the key and value of the entry as follows:
a.key=wonOscar&a.value=true
The final request would then be:
findMovies?additional=@a&a.key=wonOscar&a.value=true
Example 5 - Sub-types of Entities
Thanks to the alias feature, you can assign values having a different type than the original property, provided it's a sub-type.
Consider a person property having the com.braintribe.Person type. Let's assume we want to assign a value of a different type, for example com.braintribe.ExtendedPerson.
First, we need to assign a type signature to the alias:
@p=com.braintribe.ExtendedPerson
Without the above, you could only assign values of the original type of the person property (com.braintribe.Person)
Now, we can assign the alias to the property having the supertype com.braintribe.Person.
person=@p
Note that order is important here. If we did the above operation first, we would already assign the type of Person (
com.braintribe.Person) to the alias@p, which is not our goal.
Finally, we can assign the property itself:
p.extendedName=Thomas
As a result, the request looks as follows:
requestName?@p=com.braintribe.ExtendedPerson&person=@p&p.extendedName=Thomas
Example 6 - Object-type Properties
If necessary, it's possible to assign values to properties of the object type in your GET request. The below examples show the basic principles on how to do it:
Simple assignment
To assign a value (an integer in this case), use the below syntax:
objectProperty=11
The whole request would then be requestName?objectProperty=11.
Naturally, you can assign other types as well:
| Data type | Syntax | 
|---|---|
| integer | objectProperty=11 | 
| string | objectProperty='11'(in quotes due to type ambiguity) | 
| long | objectProperty=11L | 
| double | objectProperty=11.234D | 
| float | objectProperty=11.234F | 
| string | objectProperty=Grzegorz(no type ambiguity hence no quotes) | 
| boolean | objectProperty=true | 
| enum | objectProperty=com.braintribe.ManyValuesEnum.VALUE_007 | 
Advanced example - assigning an entity:
Let's assume we want to assign a value to the name property of the com.braintribe.Person entity, which, in turn, will be assigned to a property of the type object.
First, we need to assign an alias to the com.braintribe.Person entity.
@p=com.braintribe.Person
Now, we can assign the entity to the object property using the alias:
objectProperty=@p
Finally, we can assign the name property itself:
p.name=Joe
As a result, the request looks as follows:
requestName?@p=com.braintribe.Person&objectProperty=@p&p.name=Joe
POST, PATCH, and PUT
There are two ways of sending POST, PATCH, and PUT service request calls:
As Form Data
Tribefire supports special handling for requests that have the multipart/form-data or application/x-www-form-urlencoded format which are typically sent from native HTML browser forms. The multipart/form-data format is also the only way to send binary data (i.e. files) together with the REST request. This solution makes it easy to create HTML pages that can trigger a given service request.
Examples
- Simple request: authentication
<form action="/tribefire-services/api/v1/authenticate">
  User: 
  <input type="text" name="user">
  Password:
  <input type="password" name="password">
  <input type="submit" value="Submit">
</form>
This will perform an authentication call and return the userId as a String and open it in the same tab in the browser.
- Complex request: updating the image of a user
Imagine a request UpdateAvatarRequest that calls the UpdateAvatarProcessor which updates the avatar image of a user. The request has two properties:
- userNameof type String
- imageof type- Resource
<form action="/tribefire-services/api/v1/updateAvatar">
  User: 
  <input type="text" name="userName">
  Image:
  <input type="file" name="image">
  <input type="submit" value="Submit">
</form>
On server side this will result in an UpdateAvatarRequest where the userName is set to the value of the input field and the resource at the image property contains the binary data of the file uploaded via the form element with the same name.
Note that you can still send endpoint parameters via the form action URL:
<form action="/tribefire-services/api/v1/updateAvatar?prettyness=high&depth=1">
  User: 
  <input type="text" name="userName">
  Image:
  <input type="file" name="image">
  <input type="submit" value="Submit">
</form>
As Simple Body
You can also choose to submit your service request in the body of the REST call. The ServiceRequest is then unmarshalled from the body, in the mimeType specified in the Content-Type header.
Since only the Endpoint entity is specified in the URL/header parameter, there is no need for a prefix here, however you can use the endpoint. prefix for clarity if you want.
Since the type of the ServiceRequest may be contained in the body, it is not necessary to pass it in the URL. However, the following URLs are still valid:
- /api/v1/serviceDomain/type.signature.of.ServiceRequest: If there is also a type signature in the body, it is used instead of the type signature from the URL
- /api/v1/serviceDomain/: If there is no type signature in the body, a- 400: Bad requestis thrown.
Examples:
Method: POST
URL: http://localhost:8080/tribefire-services/api/v1/cortex/com.braintribe.model.securityservice.GetCurrentUser
Headers:
- Accept:- application/json
- Content-Type:- application/json
- gm-session-id:- someId
Body:
{
  "domainId": "cortex" 
}
Response:
{
  "_type": "com.braintribe.model.user.User",
  "id": "some-id",
  "firstName": "cortex",
  "lastName": "cortex"
}
Here are several examples of the same call which returns the current user session from a sessionId but written in different forms:
- ServiceRequesttype in URL, endpoint parameters in URL
URL: /api/v1/serviceDomain/com.braintribe.model.securityservice.GetCurrentUser?prettiness=high&sessionId=someId
Headers:
- Accept:- application/json
- Content-Type:- application/json
Body:
{
  
}
- ServiceRequesttype in URL, endpoint parameters in headers
URL: /api/v1/serviceDomain/com.braintribe.model.securityservice.GetCurrentUser?sessionId=someId
Headers:
- Accept:- application/json
- Content-Type:- application/json
- gm-prettiness:- high
Body:
{
  
}
- ServiceRequesttype in body, endpoint parameters in URL
URL: /api/v1/serviceDomain?prettiness=high&sessionId=someId
Headers:
- Accept:- application/json
- Content-Type:- application/json
Body:
{
  "_type": "com.braintribe.model.securityservice.GetCurrentUser"
}
- ServiceRequesttype in body, endpoint parameters in headers
URL: /api/v1/serviceDomain/com.braintribe.model.securityservice.GetCurrentUser
Headers:
- Accept:- application/json
- Content-Type:- application/json
- gm-prettiness:- high
- gm-session-id:- someId
Body:
{
  "_type": "com.braintribe.model.securityservice.GetCurrentUser"
}
Mapping Customization
By default, any foo.bar.ServiceRequest in tribefire may be invoked via REST with the method GET or POST and URL /api/v1/serviceDomain/foo.bar.ServiceRequest.
However, it is possible to configure custom mappings for any request via the singleton com.braintribe.model.ddra.DdraConfiguration entity in the cortex access.
For every parameter, you can define its default value. For example, entityRecurrenceDepth is the parameter supported on the REST endpoint and with defaultEntityRecurrenceDepth you can define the default (as the name suggests) for that parameter.
Much like the facade design pattern, customizing your mapping allows you to decouple the REST endpoint where a functionality is exposed from the service request that carries out the functionality. Consider the /gmql request for example. The functionality is exposed under the /tribefire-services/api/v1/gmql endpoint, but the actual service request is com.braintribe.model.accessapi.GmqlRequest. This way, if the request ever changes, the exposed endpoint will remain the same.
DdraConfiguration has a set of com.braintribe.model.ddra.DdraMapping that influence the behavior of a single mapping. DdraMapping has the following properties:
- 
methodThis property defines which HTTP method the service request is accessible with. Type | com.braintribe.model.ddra.DdraUrlMethodEnumeration Possible Values |GET,POST,PUT,DELETE,GET_POST(exposed as both GET and POST) Default Value |GET_POSTMandatory | no
- 
pathThis property defines under which URL the service request is accessible. Type | String Possible Values | any, but must start with /Mandatory | yesSupported features: - you can map different service requests under the same URL and different method (you can use this to simulate CRUD APIs to a certain extend)
- paths with multiple /are supported
 Not supported functionality: - dynamic or conditional paths are not supported, for example /my-entity/<id>where ID would be filled in from the URL
- paths with variable length are not supported, for example /my-path/*where any path starting with/my-pathwould match
 Path Value Accessible Under path=/my-requesttribefire-host/tribefire-services/api/v1/serviceDomain/my-requestpath=/my-services/service1tribefire-host/tribefire-services/api/v1/serviceDomain/my-services/service1path=/my-services/service2tribefire-host/tribefire-services/api/v1/serviceDomain/my-services/service2method=GET path=/my-crud-apiGET:tribefire-host/tribefire-services/api/v1/serviceDomain/my-crud-apimethod=POST path=/my-crud-apiPOST:tribefire-host/tribefire-services/api/v1/serviceDomain/my-crud-apimethod=PUT path=/my-crud-apiPUT:tribefire-host/tribefire-services/api/v1/serviceDomain/my-crud-apimethod=DELETE path=/my-crud-apiDELETE:tribefire-host/tribefire-services/api/v1/serviceDomain/my-crud-api
- 
requestTypeThis value contains the GmEntityTypeof the request that should be created and executed.Parameter Description Type GmEntityType, must correspond to a subtype ofServiceRequestMandatory No 
- 
transformRequestThis value contains an instance of ServiceRequest(as opposed to a type inrequestType) that should be evaluated for this path. Note that this instance is not filled from the URL parameters, headers or the body, it is executed as is.If the transformRequestis an instance ofcom.braintribe.model.service.api.HasServiceRequestandrequestTypeis defined, then an instance of typerequestTypeis created from the parameters or body and assigned to theserviceRequestproperty.The idea here is to be able apply preprocessing or postprocessing to multiple REST endpoints and to decouple it from the endpoint implementation. Parameter Description Type ServiceRequestMandatory no 
- 
defaultProjectionThis value contains the default projection to use for this REST call. Parameter Description Type String Mandatory no 
For more information on projection, see Projection.
- 
defaultDepthA simplified TraversingCriterion. For complex assemblies, it dictates how deep the returned assembly should be. Parameter Description Type com.braintribe.model.processing.ddra.endpoints.model.DdraEndpointDepthKindEnumerationPossible Values shallow,reachable,custom(number >= 0).Default Value 0Mandatory no 
- 
defaultEntityRecurrenceDepthA integer value. For complex recurrence of entities, it dictates how deep returned recurrence assembly should be. In case of 0it will use _id and _ref in result. If-1is used it will traverse recurrence tree indefinitely.Parameter Description Type Integer Possible Values number >= -1Default Value 0Mandatory no 
- 
defaultMimeTypeIdentifies default content format used for operations against content transmitted.Parameter Description Type String Possible Values application/xml,application/json,application/gm,text/xml,text/x-json,gm/xml,gm/bin,gm/json,gm/jseh,gm/jse,gm/man,gm/deprecated-jsonDefault Value application/jsonMandatory no 
- 
defaultPrettinessRepresents the level of prettiness to be used when writing the assembly back to the body of the response. Parameter Description Type com.braintribe.codec.marshaller.api.OutputPrettinessEnumerationPossible Values none,low,mid,highDefault Value midMandatory no 
- 
defaultServiceDomainIdentifies service domain to be used by default for service requests.Parameter Description Type String Possible Values anyMandatory no 
- 
defaultStabilizeOrderWhen this Boolean flag is set to true, the marshaller ensures that properties in different instances of the same entity are always in the same order. Especially useful when writeEmptyProperties=true.Parameter Description Type Boolean Possible Values true,falseDefault Value falseMandatory no 
- 
defaultTypeExplicitnessRepresents how type of objects should be marshalled. Parameter Description Type com.braintribe.codec.marshaller.api.TypeExplicitnessEnumerationPossible Values auto- The marshaller decides which of the other options it will choose.
 always- The types are made explicit to allow to preserve the correct type under all circumstances which means not to rely on any contextual information to auto convert it from another type.
 entities- The types are made explicit for entities in all cases and the other values can get simpler types if appropriate and the context of the value can give the information to reestablish the correct type with an auto conversion.
 polymorphic- he types are made explicit if the actual type cannot be reestablished from the context of the value which is the case that value is a concretization of the type given by the context.Default Value autoMandatory no 
- 
defaultWriteAbsenceInformationWhen this Boolean flag is set to true, the marshaller writes information for all absent properties. Parameter Description Type Boolean Possible Values true,falseDefault Value false
- 
defaultWriteEmptyPropertiesWhen this Boolean flag is set to true, the marshaller writes all properties that are set to null or are empty (for maps, sets and lists). Parameter Description Type Boolean Possible Values true,falseDefault Value false
- 
requestPrototypingYou can use this property as an alternative to a serialized-request. Instead of setting the serialized-request field manually (e.g. copy-pasting JSON directly into the request in Swagger), you can create a request prototype instead, and then map it to your request via DdraMapping. Note that this could be very useful to set default properties for the request. If found, the prototype will be used instead of theserialized-request.When prompted, use one of the below prototyping requests: - 
QueryPrototyping - queries for the prototype in an access. This prototype is then used when you execute your request. You need to identify the target prototype: Parameter Description accessId access_namewhere the prototype is located (you can find it in the URL after opening the access after?accessId=, for exampleaccess.demoin?accessId=access.demo#default).prototypeGlobalId GlobalIdof the target prototype.
- 
ResourcePrototyping - uses the attached resource as a prototype. In this case, you only need to attach the JSONfile:Parameter Description prototypeResource Attach your prototype here (a JSONfile).
- 
StaticPrototyping - similar to QueryPrototyping, but the prototype must be found in the Cortex model. Parameter Description prototype Assign the prototype from Cortex here. 
 
- 
Configuration in Control Center
The com.braintribe.model.ddra.DdraConfiguration may be queried and updated in Control Centre. You can find it using the Quick Access box.
The mappings are effective as soon as the changes are committed, therefore it is possible to update the configuration without restarting tribefire.
Configuration via Java
Since the configuration for the API is an entity in the cortex access, it is possible to edit it the exact same way as for entities in other accesses.
In this example, we are programmatically mapping the simple authenticate call to /api/v1/serviceDomain/login?user=xxx&password=xxx. Consult the EditDdraConfigurationExample class below:
import com.braintribe.model.ddra.DdraConfiguration;
import com.braintribe.model.ddra.DdraMapping;
import com.braintribe.model.meta.GmEntityType;
import com.braintribe.model.processing.session.GmSessionFactories;
import com.braintribe.model.processing.session.GmSessionFactoryBuilderException;
import com.braintribe.model.processing.session.api.persistence.PersistenceGmSession;
import com.braintribe.model.processing.session.api.persistence.PersistenceGmSessionFactory;
public class EditDdraConfigurationExample {
	public static void main(String[] args) throws GmSessionFactoryBuilderException {
		// get the session factory for a local instance of Tribefire
		PersistenceGmSessionFactory sessionFactory = GmSessionFactories.remote("http://localhost:8080/tribefire-services").authentication("cortex", "cortex").done();
		// open a session to the cortex access
		PersistenceGmSession session = sessionFactory.newSession("cortex");
		// get the GmEntityType for the simple authentication service request
		GmEntityType simpleAuth = session.query().entity(GmEntityType.T, "type:com.braintribe.model.securityservice.OpenUserSessionWithUserAndPassword").find();
		// create a DdraMapping
		DdraMapping mapping = session.create(DdraMapping.T);
		// no need to set this, as this is the default value
		// mapping.setMethod(DdraUrlMethod.GET_POST);
		mapping.setPath("/login");
		mapping.setRequestType(simpleAuth);
		// by default, the OpenUserSessionWithUserAndPassword returns an OpenUserSessionResponse
		// this entity contains a UserSession entity (under the property userSession), which itself contains a sessionId, let's just return the sessionId here
		mapping.setDefaultProjection("userSession.sessionId");
		// get the DdraConfiguration instance
		DdraConfiguration ddraConfiguration = session.query().entity(DdraConfiguration.T, "singleton").find();
		// add the mapping
		ddraConfiguration.getMappings().add(mapping);
		// commit
		session.commit();
	}
}
If you create a similar class and configure the DdraMapping object as specified above, you can authenticate in tribefire with a GET or POST call to /api/v1/serviceDomain/login.
Embedded Properties
It's worth knowing that if the request has any embedded properties, they are also shown in Swagger. For details on how embedding works, see Embedded metadata.
If you want embedded properties to show up only in Swagger, add the ddra use-case selector to embedded metadata.
Requesting Nested Properties
/api/v1 endpoints support accessing nested REST properties via an alias, meaning that you can execute requests even on complex property structures. Aliases can be assigned to entities, maps, lists, and even properties of the Object type. Consider the below data that we want to query with a GET request to find a movie:
FindMoviesRequest -> List<Movie>
- name
- director
 - name
 - country
 - awardsWon
   - institution
     - name
   - name
- category List<Enum> (Horror, Romance, Thriller, Comedy)
- additional
  (Map)
  Example:
    key: wonOscar
    value: true
Normally it wouldn't be possible to refer to nested data, such as director properties, and their properties. This problem was solved by adding the possibility to assign an alias to a property.
Let director have the alias d. This is expressed using the following syntax: director=@d, resulting in the possiblility to refer to properties of director:
@d.country=Austria
Note that you couldn't just say
director.country=Austria, because thendirectoris expected to be an alias.
Similarly, let the property additional of the type map have the alias a. This is expressed as additional=@a, resulting in the possibility to refer to keys and values:
a.key=wonOscar&a.value=true
An advanced GET query using an alias could then look as follows:
findMovies?director=@d&d.country=Austria&category=Horror&category=Romance&additional=@a&a.key=wonOscar&a.value=true
A real-life use-case for this feature could be sending a POST request disguised as GET, when using a third-party tool that only supports GET. In that case, we can decide to offer a request that semantically should be a POST (i.e. it creates new entries in the database) as a GET request in tribefire. This is not the recommended solution but sometimes it could be necessary to use it.
For example, we could add an extra GET mapping for model/create because we need to create a model via a simple third-party tool that does not support POST.
Try it Out
If you want to experiment with the API for yourself, use our integrated Swagger UI.
For more information, see Using Swagger UI.