Use of Product endpoints
How to use product endpoints in API
Creating a product
POST /v1/products
When creating new products, we can add more information in regards to their product structure, variation definition, classifications, workflow state and business units. You are not required to include all of these in the product setup. However, in this example we will set everything up so that you can get an idea of how to do your specific task.
Fetching the product structure and variation definition
ProductStructure clothingProductStructure = _apiClient.ProductStructures.GetProductStructures().Single(x => x.Alias == "Clothing");
The GetProductStructures
method sends an HTTP request to the /v1/productstructures endpoint. It returns a list of ProductStructure
. We use Single
to select the only product structure with the alias "Clothing".
Alternatively, you can use the /v1/productstructures/{uid} endpoint if you know the specific UID of the product structure you would like to use.
Within the ProductStructure
instance, you can now get the VariationDefinition
.
VariationDefinition clothingVariation = clothingProductStructure.VariationDefinitions.Single(x => x.Name == "Clothing");
We are now able to set the product structure and variation definition Uid on our product model.
CreateProductModel<ProductModel> productModelToBeCreated = new()
{
ProductStructureUid = clothingProductStructure.Uid,
VariationDefinitionUid = clothingVariation.Uid,
};
Adding classifications
After defining the product structure and its variations, you can improve it by adding classifications.
Classifications help organize products into groups, making it easier to manage and find product information. Each product can have multiple classifications, but only one can be the primary. This primary classification highlights the most important category for the product.
CreateProductModel<ClothingProductModel> productModelToBeCreated = new()
{
ProductStructureUid = clothingProductStructure.Uid,
VariationDefinitionUid = clothingVariation.Uid,
Classifications = new List<SetClassificationModel>
{
new SetClassificationModel()
{
CategoryId = 242,
IsPrimary = true,
OwnerReference = "made by demo api",
SortOrder = 0
},
new SetClassificationModel()
{
CategoryId = 240,
IsPrimary = false,
OwnerReference = "made by demo api",
SortOrder = 0
},
new SetClassificationModel()
{
CategoryId = 241,
IsPrimary = false,
OwnerReference = "made by demo api",
SortOrder = 0
}
},
Adding values
After setting up the clasiffications you now only need to set the values the product should be created with. Using the Struct Pim Model generator, we have generated some C# classes in order to have strongly typed models that matches the models in Struct PIM.
With those we can now specify what type of values we want. In this case we are working with clothing as seen in the code above so we would also want the values to be of type ClothingProductModel
.
CreateProductModel<ClothingProductModel> productModelToBeCreated = new()
{
ProductStructureUid = clothingProductStructure.Uid,
VariationDefinitionUid = clothingVariation.Uid,
Classifications = new List<SetClassificationModel>
{
new SetClassificationModel()
{
CategoryId = 242,
IsPrimary = true,
OwnerReference = "made by demo api",
SortOrder = 0
},
new SetClassificationModel()
{
CategoryId = 240,
IsPrimary = false,
OwnerReference = "made by demo api",
SortOrder = 0
},
new SetClassificationModel()
{
CategoryId = 241,
IsPrimary = false,
OwnerReference = "made by demo api",
SortOrder = 0
}
},
Values = new ClothingProductModel
{
Name = new List<LocalizedData<string>>
{
new LocalizedData<string> { CultureCode = "en-GB", Data = "New Awesome Gadget" },
new LocalizedData<string> { CultureCode = "da-DK", Data = "Ny Fantastisk Gadget" }
},
}
};
You can incorporate various attributes under values, such as Name
, to identify the product. The Name
attribute is of type LocalizedData<string>
, allowing the name to vary by language in the PIM. This is done by specifying the CultureCode
and Data
for the Name
attribute.
Now we are mostly done. The remaining information that can be defined besides different values are businessunits that the product has relation to, and the workflow it is assigned to.
CreateProductModel<ClothingProductModel> productModelToBeCreated = new()
{
ProductStructureUid = clothingProductStructure.Uid,
VariationDefinitionUid = clothingVariation.Uid,
WorkflowStateUid = null,
In the example above we set the WorkflowStateUid
as null, since we do not have a workflow for.
When adding business units to the product we must first retrieve the business unit. We do this through the /v1/businessunits endpoint. Just like previously with product we select the business unit through its alias "ClothingUnit".
BusinessUnitModel clothingBusinessUnit = _apiClient.BusinessUnits.GetBusinessUnits().Single(x => x.Alias == "ClothingUnit");
Once we have the business unit we can proceed to add it to the product being created.
CreateProductModel<ClothingProductModel> productModelToBeCreated = new()
{
ProductStructureUid = clothingProductStructure.Uid,
VariationDefinitionUid = clothingVariation.Uid,
WorkflowStateUid = null,
BusinessUnits = new List<BusinessUnitRelationModel>
{
new BusinessUnitRelationModel
{
BusinessUnitUid = clothingBusinessUnit.Uid,
},
},
With everything now set up we can conclude the example by adding the product to the PIM throught the use of the /v1/products enpoint.
_apiClient.Products.CreateProduct(productModelToBeCreated);
Using the /search endpoint
POST /v1/products/search
When using the search endpoint to find product IDs, the process can seem complex initially, especially when multiple conditions are involved, as shown in the example above.
In the following example we will demystify the request body and set an example to give a better idea on how to perform this specific task.
SearchModel search = new SearchModel();
Before we can use the search endpoint we need to first understand how to use the SearchModel
and set up conditions.
We start by instantiating the SearchModel
publicating it with information. We begin with the IncludeArchived
property which is a boolean we can set to true or false dependent on if you want to include archived items in result.
SearchModel search = new SearchModel()
{
IncludeArchived = false,
QueryModel = new BooleanQueryModel
{
Once this is done we begin setting up the abstract QueryModel
which can either be of type SimpleQueryModel
or BooleanQueryModel
.
SimpleQueryModel: Simple query model used for querying specific fields. Used for specifying fields to filter search by.
BooleanQueryModel: Query wrapper for sub queries where the BooleanOperator operates between the sub queries. Allows for nested queries.
In the example above we want to set up multiple search conditions. For that we would need SubQueries
which only BooleanQueryModel can contain. However, before adding them we need to specify with a BooleanOperator
if at least one or all conditions in the SubQueries
must match by asigning the boolean the value 1 or 0. By selecting the BooleanOperator.And
(0), we have choosen that all conditions must match for the search to pick up the product id.
SearchModel search = new SearchModel()
{
IncludeArchived = false,
QueryModel = new BooleanQueryModel
{
BooleanOperator = BooleanOperator.And,
SubQueries = new List<QueryModel>
{
new SimpleQueryModel
{
Filters = new List<FieldFilterModel>
{
new FieldFilterModel { }
The SubQueries
contain a list of SimpleQueryModels
that each can contain a list of FieldFilterModels
where the conditions for the search are written. In the scenario where a SimpleQueryModel
contains multiple FieldFilterModels
, it is adviced to add a BooleanOperator
in order to specify if all or only one condition must match.
SearchModel search = new SearchModel()
{
IncludeArchived = false,
QueryModel = new BooleanQueryModel
{
BooleanOperator = BooleanOperator.And,
SubQueries = new List<QueryModel>
{
new SimpleQueryModel
{
Filters = new List<FieldFilterModel>
{
new FieldFilterModel
{
FieldUid = "",
QueryOperator = QueryOperator.Equals,
FilterValue = ""
}
The FieldFilterModel
contains three properties, as seen in the example above.
FieldUid
: Uid of field to query.QueryOperator
: Can be any of:Equals
/ 0 (Value must start with FilterValue)WildcardEquals
/ 1 (Value must be smaller than FilterValue)SmallerThan
/ 2 (Value must be smaller than FilterValue)LargerThan
/ 3 (Value must be larger than FilterValue)IsEmpty
/ 4 (Value must be empty)IsNotEmpty
/ 5 (Value must not be empty)Contains
/ 6 (Value must contain FilterValue)NotContains
/ 7 (Value must not contain FilterValue)
NotEquals
/ 8 (Value must not be exactly equal to FilterValue (not considering casing))NotWildcardEquals
/ 9 (Value must not start with FilterValue)InList
/ 10 (Item field value must match any of the in provided values in FilterList)
FilterValue
: Value to filter for using the QueryOperator. When QueryOperator is "InList", FilterValue must be an array of values to query for.'
A good way to get all queryable fields from the PIM is through the endpoint /v1/products/queryablefields.
With this you can set up simple or complex SearchModels
using the /v1/products/search endpoint.
Example of searching for products
The following example demonstrate a query that looks for products with "Adidas" as the brand, "Portugal" as the country of origin, and having at least 15 variants.
SearchModel searchModel = new SearchModel()
{
IncludeArchived = false,
QueryModel = new BooleanQueryModel()
{
BooleanOperator = BooleanOperator.And,
SubQueries = new()
{
new SimpleQueryModel()
{
BooleanOperator = BooleanOperator.And,
Filters = new List<FieldFilterModel>()
{
// Country of origin
new FieldFilterModel()
{
FieldUid = "e2342c65-3def-4f57-9fe7-3fe9d3f093ed_en-GB_NA",
QueryOperator = QueryOperator.Equals,
FilterValue = "Portugal"
},
// Brand
new FieldFilterModel()
{
FieldUid = "f886acd6-1397-4004-aba0-a3b2d6180151_NA_NA",
QueryOperator = QueryOperator.Equals,
FilterValue = "Adidas"
}
}
},
new SimpleQueryModel()
{
Filters = new()
{
// Number of variants
new FieldFilterModel()
{
FieldUid = "PIM_VariantsCount",
QueryOperator = QueryOperator.LargerThan,
FilterValue = "14"
}
}
}
}
}
};
List<int> queryResult = _apiClient.Products.Search(searchModel);
Last updated