SoftTypes
Caution
Sample code provided in here is for demonstration and educational purposes only which provides customers with programming information regarding the products and is not intended for use in a production environment. All production code should always follow development best practices. All sample code here is supplied "AS IS" without any warranties or support.
The provided C# code sample below uses HttpClient
to make the REST calls.
Warning
A common mistake when using HttpClient
is to use multiple instances of the
HttpClient
. You should reuse the same instance within an application.
As explained in the SoftTypes features section, the input and output schemas of a SoftType define the contracts for REST APIs for creating, reading, and updating a SoftType instance.
In this example we will use a very simple SoftType identified as Person
.
SoftType Resource
Definition
The resource for SoftTypes can be found at:
GET : /api/space/{spaceId}/softtype
Note
This will only return minimal information about the SoftType. To get the full definition (data section, schemas, etc.) you must use the specific route to a single SoftType. See the next example.
The resource for a specific SoftType can be found at:
GET : /api/space/{spaceId}/toftyype/{SoftTypeId}
Requesting the last example will return the full SoftType definition for the SoftType with the specified identifier.
Instance
The resource for a SoftType instance can be found on a set of URIs:
GET : /api/space/{spaceId}/softtype/{uuid}
PUT : /api/space/{spaceId}/softtype/{uuid}
The example above shows the generic SoftType route not specifying the SoftType Id. This allows for GET and PUT operations since we have the database id of the SoftType instance.
GET : /api/space/{spaceId}/softtype/{SoftTypeId}/{uuid}
PUT : /api/space/{spaceId}/softtype/{SoftTypeId}/{uuid}
POST : /api/space/{spaceId}/softtype/{SoftTypeId}
The example above shows the specific SoftType route with the SoftType id specified. This allows for GET, PUT, and POST operations. The input/output schema is not specified. This will make the API use the default input and output schemas defined for the SoftType.
GET : /api/space/{spaceId}/softtype/{SoftTypeId}/{schemaId}/{uuid}
PUT : /api/space/{spaceId}/softtype/{SoftTypeId}/{schemaId}/{uuid}
POST : /api/space/{spaceId}/softtype/{SoftTypeId}/{schemaId}
The example above shows the specific SoftType route with the SoftType id specified as well as the schema id specified. This allows for GET, PUT, and POST operations. The API will use the schema defined within the route.
SoftType Compliance
When creating or updating a SoftType instance the API will always validate the input against the schema used. After a schema validation is successful the SoftType engine will validate the rules defined in the data section of the SoftType configuration.
Note
It is possible to have other rules in the schema than the rules that you configure in the data section. Typically the schema rules would be stricter. However, in the end it is always the rules setup in the data section of a SoftType that has "final say" in the evaluation.
When creating a new instance using the REST APIs, the validation will always be "strict", i.e. when using the REST APIs to create new instances you must always fulfill the SoftType schema rules and the SoftType data rules.
When updating an instance using PUT/PATCH there can however be a different behavior. Since it is possible to run imports that are allowed to bypass the SoftType rules (as long as the model rules are not broken) you might end up in a situation where you want to update "incomplete" SoftTypes.
If a SoftType instance does not fulfill the data section rules of a SoftType, the Unit of Information for that instance will be tagged as not being "SoftType compliant". I.e. there is a Boolean flag on Unit of Information stating whether or not an instance is compliant with its SoftType configuration.
- If an instance is tagged as SoftType compliant a PUT/PATCH will use the strict validation. I.e. you cannot use the API to go from compliant to non compliant.
- If an instance is tagged as Not SoftType compliant a PUT/PATCH will not use a strict validation. I.e. you can update parts of the SoftType and let it stay in the non compliant mode. You can also update the SoftType instance to become compliant. Once an instance is compliant, rules in the first bullet will take effect.
SoftType POST C# Example
In this first example we will create a new instance of the Person
SoftType.
The person SoftType has one input schema.
{
"$id": "defaultIn",
"definition": {
"type": "object",
"required": [ "id", "firstName", "lastName" ],
"properties": {
"id": {
"type": "string"
},
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
}
}
}
}
To instantiate a new Person
we build up a new JSON Object and post it to the API. We
have the Authorization and Information Filter headers set on the client according to the
previous examples.
The content of the POST will be a JSON object according to the default input schema of
Person
.
{
"id": "945c22bb-0eae-499b-89f7-6a3c6aab3ba9",
"firstName": "First",
"lastName": "Last"
}
var person = new JObject();
person["id"] = Guid.NewGuid().ToString();
person["firstName"] = "First";
person["lastName"] = "Last";
var jsonContent = new StringContent(person.ToString(), Encoding.UTF8, "application/json");
var postResponse = await httpClient.PostAsync("https://server.machine.net/api/space/incontrol/softtype/Person", jsonContent);
postResponse.EnsureSuccessStatusCode();
Note
The PostAsJsonAsync
method comes from the System.Net.Http.Formatting
extension library.
If we managed to create an instance of Person
we will get the 201
response code back. If we look at the
Location
header of postResponse
we can also see that we get a URI for getting the newly created Person
.
https://server.machine.net/api/space/incontrol/softtype/Person/5bc2d257b0ab4021f500020000000000
SoftType GET C# Example
The Location gives us the route without the output schema id that when used will load
the Person
instance according to the default output schema (i.e. using the URI in a GET request).
var getResponse = await httpClient.GetAsync(postResponse.Headers.Location);
string getContent = await getResponse.Content.ReadAsStringAsync();
var personGet = JObject.Parse(getContent);
{
"href": "https://server.machine.net/api/space/incontrol/softtype/Person/0100000000000000160101000000",
"data": {
"$availability": "Active",
"$oid": "0100000000000000160101000000",
"$softType": "Person",
"$version": 1,
"id": "a79503fb-abb5-4cc9-99d4-a0658e387f48",
"firstName": "First",
"lastName": "Last"
},
"version": 1,
"links": [
{
"rel": "definition",
"href": "https://server.machine.net/api/space/incontrol/definition/softtype/Person",
"method": "GET"
},
{
"rel": "search",
"href": "https://server.machine.net/api/space/incontrol/search/{queryDefinitionId}{?term}&softType=Person",
"method": "GET"
},
{
"rel": "structureDefinitions",
"href": "https://server.machine.net/api/space/incontrol/structure/0100000000000000160101000000",
"method": "GET"
},
{
"rel": "effectivityHistory",
"href": "https://server.machine.net/api/space/incontrol/softtype/effectivityHistory/Person/0100000000000000160101000000/{portId}",
"method": "GET"
},
{
"rel": "update",
"href": "https://server.machine.net/api/space/incontrol/softtype/Person/{schemaId}/0100000000000000160101000000",
"method": "PUT"
},
{
"rel": "delete",
"href": "https://server.machine.net/api/space/incontrol/softtype/Person/0100000000000000160101000000",
"method": "DELETE"
}
]
}
Looking at the JSON result from the GET operation we can see that we get a JSON object
with href
, data
, version
, and links
.
href
: shows the URI from where we got the payload (same as the URI we used in the GET request)data
: ThePerson
instance according to one of its output schemas (in this case the one configured as default)- We can also see that the system has added
$oid
,$softType
and$version
. These are not part of the output schemas but the system will always add this information.$oid
is the database id of the key instance for the SoftType.$softType
is the SoftType id of the instance.$version
is the system version number of the current instance. Any updates to the instance will increase the$version
number.
- We can also see that the system has added
version
: The current application version (not PLM version) of the data. Theversion
value retrieved from aGET
operation should be set as theSAs-UOIVersion
header value when sendingPUT
andPATCH
requests.links
: An array with operations available on this instance. This array depends on the current users access to the instance. In this example, thesearch
cannot be used directly, instead the API Consumer must use the pattern provided to pick an appropriate query and terms that the query might require. More on Queries in the next section.
Tip
References to other SoftType instances from within a SoftType will always include $oid
, $softType
, and $version
- no
matter if the reference is resolved in the output schema configuration or not.
PowerShell Example
Continuing from our previous PowerShell examples it is possible to create an instance of a Person
using the
method POST with the Invoke-RestMethod.
$person = @{
"id" = "945c22bb-0eae-499b-89f7-6a3c6aab3ba9";
"firstName" = "First";
"lastName" = "Last"
} | ConvertTo-Json
Invoke-RestMethod -Uri "https://server.machine.net/api/space/incontrol/softtype/Person" -Method Post -ContentType "application/json" -Headers $bearerHeader -Body $person
One difference here is when using Invoke-RestMethod
we can not get to the Location header of the response when
the POST is successful. However, the Invoke-WebRequest
returns the response headers of the request.
$postWebRequest = Invoke-WebRequest -Uri "https://server.machine.net/api/space/incontrol/softtype/Person" -Method Post -ContentType "application/json" -Headers $bearerHeader -Body $person
Write-Host $postWebRequest.Headers.Location
In the example above we can use $postWebRequest.Headers.Location
as the URI for a GET request in
order to load the newly created Person
instance.
Download sample
The code example provided in this document can be downloaded in a sample project.