PIM Systems

Struct PIM API v4: Komplet guide til komplekse attributter (Nu med globale lister!)

En omfattende guide til at bruge komplekse attributter i Struct PIM API v4, inklusiv den udokumenterede mulighed for at bruge dem i globale lister. Indeholder praktiske kodeeksempler og implementeringer fra den virkelige verden.

Udgivet 27. januar 2025
18 min læsning
Opdateret 30. januar 2025
Sivert Kjøller Bertelsen
Struct
API
Tutorial
Integration
Komplekse Attributter

Oversigt

Komplekse attributter i Struct PIM giver dig mulighed for at skabe strukturerede, indlejrede data inden for dine produktoplysninger. I modsætning til simple attributter der gemmer enkeltværdier, indeholder komplekse attributter flere under-attributter der arbejder sammen om at danne en sammenhængende datastruktur.

Vigtige fordele

  • Organiserede data: Grupper relaterede attributter logisk (f.eks. tekniske specifikationer, dimensioner)
  • Genanvendelige strukturer: Definer én gang, brug på tværs af flere produktstrukturer
  • Rig datamodellering: Understøt komplekse produktinformationskrav
  • UI-fleksibilitet: Kontroller hvordan indlejrede data vises og gengives

Forståelse af komplekse attributter

Hvad er komplekse attributter?

En kompleks attribut er en container der indeholder flere under-attributter. Tænk på det som et struktureret objekt i programmering:

Kompleks attributstruktur

Eksempel der viser forskellen mellem simple og komplekse attributter

javascript
// Simple attributter gemmer enkeltværdier
ProductName: "iPhone 15 Pro"
Price: 999.99

// Komplekse attributter gemmer strukturerede objekter
TechnicalSpecs: {
  ModelNumber: "A2848",
  PowerRating: 120,
  Voltage: "220V",
  IsEnergyEfficient: true
}

// Arkitektur
ComplexAttribute
├── SubAttribute 1 (TextAttribute)
├── SubAttribute 2 (NumberAttribute) 
├── SubAttribute 3 (BooleanAttribute)
└── SubAttribute N (Enhver understøttet type)

API-skema vs. virkelighed

Dokumentationskløften

Den officielle Swagger-dokumentation viser et forenklet skema, men vores empiriske test afslørede den faktiske fungerende struktur:

Dokumentation vs. virkelighed

Hvad Swagger-dokumenterne foreslår vs. hvad der faktisk virker

json
// ❌ Hvad Swagger-dokumenterne foreslår:
{
  "alias": "TechSpecs",
  "name": "Technical Specifications",
  "type": "ComplexAttribute",
  "configuration": {
    "subAttributes": [...]
  }
}

// ✅ Hvad der faktisk virker:
{
  "Uid": "uuid-here",
  "Alias": "TechSpecs", 
  "BackofficeName": "Technical Specifications",
  "AttributeType": "ComplexAttribute",
  "Localized": false,
  "ReadOnly": false,
  "Mandatory": false,
  "Columns": 12,
  "Unchangeable": false,
  "DisableRevisionLogging": false,
  "DisableIndexing": false,
  "SubAttributes": [
    // Fulde attributdefinitioner her, ikke referencer
  ],
  "RenderValuesForAttributeFieldUids": [],
  "RenderValuesForBackofficeAttributeFieldUids": [],
  "RenderedValueSeparator": null,
  "RenderedValueInBackofficeSeparator": null
}

Oprettelse af komplekse attributter

Grundstruktur

Hver kompleks attribut skal indeholde disse essentielle egenskaber:

TypeScript interface

Komplet interface for komplekse attributter

typescript
interface ComplexAttributeBase {
  Uid: string;                    // Påkrævet: Generer UUID
  Alias: string;                  // Påkrævet: Unik identifier
  BackofficeName: string;         // Påkrævet: Visningsnavn
  AttributeType: 'ComplexAttribute';
  Localized: boolean;             // Normalt false
  ReadOnly: boolean;              // Normalt false
  Mandatory: boolean;             // Normalt false
  Columns: number;                // 1-12, normalt 12 for fuld bredde
  Unchangeable: boolean;          // Normalt false
  DisableRevisionLogging: boolean; // Normalt false
  DisableIndexing: boolean;       // Normalt false
  SubAttributes: SubAttribute[];  // De indlejrede attributter
}

Trin-for-trin oprettelse

Følg disse trin for at oprette en kompleks attribut:

Oprettelsesproces

  1. Generer unikke ID'er for den komplekse attribut og hver under-attribut
  2. Definer under-attributter med komplette attributdefinitioner
  3. Sammensæt den komplekse attribut med alle påkrævede egenskaber
  4. Opret via API-endpoint med ordentlig fejlhåndtering

Praktiske eksempler

Eksempel 1: Tekniske specifikationer

Perfekt til produkter med flere tekniske detaljer:

Eksempel på tekniske specifikationer

Komplet eksempel på en kompleks attribut for tekniske specifikationer

typescript
const technicalSpecsAttribute = {
  Uid: generateGuid(),
  Alias: 'TechnicalSpecs',
  BackofficeName: 'Tekniske specifikationer', 
  AttributeType: 'ComplexAttribute',
  Localized: false,
  ReadOnly: false,
  Mandatory: false,
  Columns: 12,
  Unchangeable: false,
  DisableRevisionLogging: false,
  DisableIndexing: false,
  SubAttributes: [
    {
      Uid: generateGuid(),
      Alias: 'ModelNumber',
      BackofficeName: 'Modelnummer',
      AttributeType: 'TextAttribute',
      Localized: false,
      ReadOnly: false,
      Mandatory: false,
      Columns: 6,
      Unchangeable: false,
      DisableRevisionLogging: false,
      DisableIndexing: false,
      MaxLength: 100,
      UseMultiRowInput: false,
      UseRichText: false,
      ShowCharacterCount: false
    },
    {
      Uid: generateGuid(),
      Alias: 'PowerRating', 
      BackofficeName: 'Effektforbrug (W)',
      AttributeType: 'NumberAttribute',
      Localized: false,
      ReadOnly: false,
      Mandatory: false,
      Columns: 6,
      Unchangeable: false,
      DisableRevisionLogging: false,
      DisableIndexing: false,
      NumberOfDecimals: 0,
      Min: 0,
      Max: 2000,
      Unit: 'W'
    },
    {
      Uid: generateGuid(),
      Alias: 'IsEnergyEfficient',
      BackofficeName: 'Energieffektiv',
      AttributeType: 'BooleanAttribute',
      Localized: false,
      ReadOnly: false,
      Mandatory: false,
      Columns: 6,
      Unchangeable: false,
      DisableRevisionLogging: false,
      DisableIndexing: false
    }
  ],
  RenderValuesForAttributeFieldUids: [],
  RenderValuesForBackofficeAttributeFieldUids: [],
  RenderedValueSeparator: null,
  RenderedValueInBackofficeSeparator: null
};

⚡ Komplekse attributter i globale lister (Vigtig opdagelse)

Breaking: Komplekse attributter VIRKER i globale lister!

I modsætning til hvad man kunne antage fra dokumentationen, UNDERSTØTTER Struct PIM komplekse attributter for globale lister. Dette er en kraftfuld, udokumenteret funktion der muliggør rige, strukturerede datamodeller for globale listeværdier.

I stedet for simple tekstværdier i dine globale lister, kan du nu have rige objekter med flere egenskaber som brandnavn, kode, beskrivelse, logo URL osv. Dette muliggør sofistikerede use cases som:

Forretningsværdi

  • Master Feature Dictionary (MFD): Komplekse featuredefinitioner med metadata, ejerskab, dokumentationslinks
  • Rige referencedata: Globale lister med flere attributter per indtastning (kode, navn, beskrivelse, sorteringsrækkefølge)
  • Strukturerede opslag: Multi-felt dropdown-muligheder der bærer yderligere kontekst
  • Brand management: Komplet brandinformation inklusiv logoer, koder og beskrivelser i én global liste

Kritiske implementeringsdetaljer

  • Brug ComplexAttribute (IKKE CompositeAttribute) som AttributeType
  • Brug SubAttributes array (IKKE CompositeFields) til at definere indlejrede felter
  • Hver SubAttribute skal være en komplet attributdefinition med alle påkrævede egenskaber
  • Attributtyper skal matche præcist: NumberAttribute ikke NumericAttribute, TextAttribute ikke Text

Global liste med komplekse attributter eksempel

Fungerende eksempel på en global liste med kompleks struktur for rige branddata

typescript
// ✅ VIRKER: Global liste med komplekse attributter
const brandGlobalListAttribute = {
  Uid: generateGuid(),
  Alias: 'BrandList',
  BackofficeName: 'Brandinformation',
  AttributeType: 'ComplexAttribute', // SKAL være ComplexAttribute
  Localized: false,
  ReadOnly: false,
  Mandatory: false,
  Columns: 12,
  Unchangeable: false,
  DisableRevisionLogging: false,
  DisableIndexing: false,
  SubAttributes: [ // SKAL være SubAttributes, ikke CompositeFields
    {
      Uid: generateGuid(),
      Alias: 'BrandName',
      BackofficeName: 'Brandnavn',
      AttributeType: 'TextAttribute', // SKAL være TextAttribute
      Localized: false,
      ReadOnly: false,
      Mandatory: true,
      Columns: 6,
      Unchangeable: false,
      DisableRevisionLogging: false,
      DisableIndexing: false,
      MaxLength: 255,
      UseMultiRowInput: false,
      UseRichText: false,
      ShowCharacterCount: false
    },
    {
      Uid: generateGuid(),
      Alias: 'BrandCode',
      BackofficeName: 'Brandkode',
      AttributeType: 'TextAttribute',
      Localized: false,
      ReadOnly: false,
      Mandatory: true,
      Columns: 3,
      Unchangeable: false,
      DisableRevisionLogging: false,
      DisableIndexing: false,
      MaxLength: 50
    },
    {
      Uid: generateGuid(),
      Alias: 'BrandLogoUrl',
      BackofficeName: 'Logo URL',
      AttributeType: 'TextAttribute',
      Localized: false,
      ReadOnly: false,
      Mandatory: false,
      Columns: 12,
      Unchangeable: false,
      DisableRevisionLogging: false,
      DisableIndexing: false,
      MaxLength: 500
    },
    {
      Uid: generateGuid(),
      Alias: 'IsActive',
      BackofficeName: 'Aktiv',
      AttributeType: 'BooleanAttribute',
      Localized: false,
      ReadOnly: false,
      Mandatory: false,
      Columns: 3,
      Unchangeable: false,
      DisableRevisionLogging: false,
      DisableIndexing: false
    }
  ],
  RenderValuesForAttributeFieldUids: [],
  RenderValuesForBackofficeAttributeFieldUids: [],
  RenderedValueSeparator: null,
  RenderedValueInBackofficeSeparator: null
};

// Almindelige fejl og løsninger:
// ❌ "No implementation was found for: CompositeAttribute" → Brug ComplexAttribute
// ❌ "No implementation was found for: NumericAttribute" → Brug NumberAttribute
// ❌ "No implementation was found for: Text" → Brug TextAttribute
// ⚠️ Elasticsearch indekseringsfejl kan forekomme men indikerer ikke konfigurationsproblemer

Eksempel 2: Fysiske dimensioner

Ideelt til produkter der kræver størrelsesspecifikationer med tilpassede separatorer til visning:

Eksempel på fysiske dimensioner

Kompleks attribut for produktdimensioner med tilpasset gengivelse

typescript
const dimensionsAttribute = {
  Uid: generateGuid(),
  Alias: 'PhysicalDimensions',
  BackofficeName: 'Fysiske dimensioner',
  AttributeType: 'ComplexAttribute',
  Localized: false,
  ReadOnly: false,
  Mandatory: false,
  Columns: 12,
  Unchangeable: false,
  DisableRevisionLogging: false,
  DisableIndexing: false,
  SubAttributes: [
    {
      Uid: generateGuid(),
      Alias: 'Length',
      BackofficeName: 'Længde (cm)',
      AttributeType: 'NumberAttribute',
      Localized: false,
      ReadOnly: false,
      Mandatory: false,
      Columns: 4,
      Unchangeable: false,
      DisableRevisionLogging: false,
      DisableIndexing: false,
      NumberOfDecimals: 2,
      Min: 0,
      Max: 1000,
      Unit: 'cm'
    },
    {
      Uid: generateGuid(),
      Alias: 'Width',
      BackofficeName: 'Bredde (cm)', 
      AttributeType: 'NumberAttribute',
      Localized: false,
      ReadOnly: false,
      Mandatory: false,
      Columns: 4,
      Unchangeable: false,
      DisableRevisionLogging: false,
      DisableIndexing: false,
      NumberOfDecimals: 2,
      Min: 0,
      Max: 1000,
      Unit: 'cm'
    },
    {
      Uid: generateGuid(),
      Alias: 'Height',
      BackofficeName: 'Højde (cm)',
      AttributeType: 'NumberAttribute',
      Localized: false,
      ReadOnly: false,
      Mandatory: false,
      Columns: 4,
      Unchangeable: false,
      DisableRevisionLogging: false,
      DisableIndexing: false,
      NumberOfDecimals: 2,
      Min: 0,
      Max: 1000,
      Unit: 'cm'
    }
  ],
  // Tilpassede separatorer til visning: "100 × 50 × 25"
  RenderValuesForAttributeFieldUids: [],
  RenderValuesForBackofficeAttributeFieldUids: [],
  RenderedValueSeparator: ' × ',
  RenderedValueInBackofficeSeparator: ' × '
};

Bedste praksis

1. Navngivningskonventioner

Følg konsistente navngivningsmønstre:

Navngivningsretningslinjer

  • Aliases: Brug PascalCase uden mellemrum (TechnicalSpecs, PhysicalDimensions)
  • BackofficeNames: Brug læsbare navne med mellemrum (Tekniske specifikationer, Fysiske dimensioner)
  • SubAttribute Aliases: Brug beskrivende navne (ModelNumber, PowerRating, IsEnergyEfficient)

UI-layout (kolonner)

  • Komplekse attributter: Brug fuld bredde (Columns: 12)
  • Under-attributter: Halv bredde til parede felter (Columns: 6)
  • Dimensioner: Tredje bredde til trillinger (Columns: 4)
  • Kompakte felter: Fjerde bredde (Columns: 3)

Fejlfinding

Almindelige problemer og løsninger

Hyppige problemer

  • "The attribute field is required" fejl: Send attributobjekt direkte, ikke indpakket i container
  • SubAttribute oprettelsesfejl: Sikr at hver SubAttribute har alle påkrævede basisegenskaber
  • Type valideringsfejl: Brug type casting til API-kald (as any)
  • Kompleks attribut vises ikke: Tjek Columns layout og gengivelseskonfiguration

Fejlfindingstips

  • Log fulde payloads: Log altid den komplette anmodning før afsendelse
  • Tjek response data: API-fejl indeholder ofte detaljerede valideringsmeddelelser
  • Valider UUIDs: Sikr at alle Uid-felter indeholder gyldige UUIDs
  • Test SubAttributes individuelt: Opret simple attributter først, derefter komplekse
  • Eksporter og sammenlign: Brug eksportfunktionalitet til at se hvordan eksisterende komplekse attributter er struktureret

Eksempel på fejlhåndtering

Korrekt fejlhåndtering ved oprettelse af komplekse attributter

typescript
// Korrekt fejlhåndtering
try {
  await client.createAttribute(complexAttribute as any);
  console.log(`✅ Kompleks attribut oprettet: ${complexAttribute.Alias}`);
} catch (error) {
  console.error(`❌ Kunne ikke oprette ${complexAttribute.Alias}:`, error.response?.data);
  // Log detaljeret fejlinformation til debugging
}

// API Response mønstre
// Succes Response: "" (tom streng)
// Fejl Response:
{
  "error": "Validation failed",
  "details": {
    "SubAttributes[0].Alias": "The field is required",
    "SubAttributes[1].NumberOfDecimals": "Must be between 0 and 10"
  }
}

Konklusion

Komplekse attributter er en kraftfuld funktion i Struct PIM der muliggør sofistikeret produktdatamodellering. Ved at forstå de faktiske API-krav (ikke kun Swagger-dokumentationen) og følge mønstrene beskrevet i denne guide, kan du succesfuldt implementere komplekse indlejrede datastrukturer til dine produkter.

Nøgleindsigterne fra vores empiriske test:

Vigtigste pointer

  1. Brug det komplette attributskema - stol ikke udelukkende på Swagger-dokumenter
  2. Under-attributter skal være komplette attributdefinitioner - ikke kun referencer
  3. Alle basisegenskaber er påkrævede - selvom de synes valgfrie
  4. TypeScript casting kan være nødvendigt - API'en er mere fleksibel end types antyder
  5. Test grundigt og iterer - komplekse attributter har mange bevægelige dele

Relaterede Artikler

Detailed technical review of Struct PIM system including configurable product models, API capabilities, and real-world implementation insights.

Struct
Configurable
PIM
Læs Artikel

Omfattende tutorial til Bluestone PIM API integration. Lær autentificering, opret attributtyper, styr produkter og byg komplette PIM workflows med TypeScript eksempler.

Bluestone
API
TypeScript
Læs Artikel

Praktisk guide til PIM system udvælgelse med fokus på datamodel test, attribut krav og leverandør-neutral evaluering.

PIM
Udvælgelse
Guide
Læs Artikel