or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

authentication.mdindex.mdoperations.mdpipeline.mdpolicies.mdserialization.mdservice-client.md
tile.json

policies.mddocs/

Pipeline Policies

Extensible policy system for HTTP request/response processing. Pipeline policies provide a modular way to handle cross-cutting concerns like serialization, deserialization, authentication, logging, and retry logic.

Capabilities

Serialization Policy

Pipeline policy that handles request serialization, converting JavaScript objects to HTTP request payloads based on operation specifications.

/**
 * Creates pipeline policy for request serialization
 * Converts JavaScript objects to HTTP request bodies and parameters
 * @param options - Configuration options for serialization behavior
 * @returns PipelinePolicy for request serialization
 */
function serializationPolicy(options?: SerializationPolicyOptions): PipelinePolicy;

/**
 * Unique identifier for the serialization policy
 */
const serializationPolicyName: string; // "serializationPolicy"

Deserialization Policy

Pipeline policy that handles response deserialization, converting HTTP response payloads back to JavaScript objects.

/**
 * Creates pipeline policy for response deserialization
 * Converts HTTP response bodies to JavaScript objects based on operation specifications
 * @param options - Configuration options for deserialization behavior
 * @returns PipelinePolicy for response deserialization
 */
function deserializationPolicy(options?: DeserializationPolicyOptions): PipelinePolicy;

/**
 * Unique identifier for the deserialization policy
 */
const deserializationPolicyName: string; // "deserializationPolicy"

Policy Configuration

Serialization Policy Options

Configuration options for controlling request serialization behavior, including custom XML handling and serializer settings.

/**
 * Configuration options for serialization policy
 */
interface SerializationPolicyOptions {
  /**
   * Custom XML stringifier function for converting objects to XML strings
   * @param obj - Object to convert to XML
   * @param opts - Additional options for XML generation
   * @returns XML string representation
   */
  stringifyXML?: (obj: unknown, opts?: any) => string;
  
  /**
   * Serializer configuration options
   */
  serializerOptions?: SerializerOptions;
}

Deserialization Policy Options

Configuration options for controlling response deserialization behavior, including content type detection and custom XML parsing.

/**
 * Configuration options for deserialization policy
 */
interface DeserializationPolicyOptions {
  /**
   * Expected content types for automatic deserialization
   */
  expectedContentTypes?: DeserializationContentTypes;
  
  /**
   * Custom XML parser function for converting XML strings to objects
   * @param str - XML string to parse
   * @param opts - Additional options for XML parsing
   * @returns Parsed object representation
   */
  parseXML?: (str: string, opts?: any) => Promise<any>;
  
  /**
   * Serializer configuration options
   */
  serializerOptions?: SerializerOptions;
}

/**
 * Content type patterns for deserialization
 */
interface DeserializationContentTypes {
  /** String patterns for JSON content types */
  json?: string[];
  /** String patterns for XML content types */
  xml?: string[];
}

Usage Examples

Basic Policy Usage

import { 
  serializationPolicy,
  deserializationPolicy,
  createClientPipeline 
} from "@azure/core-client";

// Policies are automatically added by createClientPipeline
const pipeline = createClientPipeline();

// Manual policy addition (not typically needed)
pipeline.addPolicy(serializationPolicy());
pipeline.addPolicy(deserializationPolicy());

Custom Serialization Policy

import { 
  serializationPolicy,
  createClientPipeline 
} from "@azure/core-client";

// Custom XML stringifier
const customXmlStringifier = (obj: unknown): string => {
  // Custom XML generation logic
  return `<custom>${JSON.stringify(obj)}</custom>`;
};

const pipeline = createClientPipeline({
  serializationOptions: {
    stringifyXML: customXmlStringifier,
    serializerOptions: {
      xml: {
        rootName: "customRoot",
        includeRoot: true
      }
    }
  }
});

Custom Deserialization Policy

import { 
  deserializationPolicy,
  createClientPipeline 
} from "@azure/core-client";

// Custom XML parser
const customXmlParser = async (xmlString: string): Promise<any> => {
  // Custom XML parsing logic
  const parser = new DOMParser();
  const doc = parser.parseFromString(xmlString, "text/xml");
  return convertDomToObject(doc);
};

const pipeline = createClientPipeline({
  deserializationOptions: {
    parseXML: customXmlParser,
    expectedContentTypes: {
      xml: ["application/xml", "text/xml", "application/soap+xml"],
      json: ["application/json", "text/json"]
    },
    serializerOptions: {
      xml: {
        xmlCharKey: "#text",
        includeRoot: false
      }
    }
  }
});

Policy Ordering and Integration

import { 
  createClientPipeline,
  serializationPolicyName,
  deserializationPolicyName 
} from "@azure/core-client";
import { 
  logPolicy,
  retryPolicy,
  bearerTokenAuthenticationPolicy 
} from "@azure/core-rest-pipeline";

// Create pipeline with custom policy ordering
const pipeline = createClientPipeline({
  credentialOptions: {
    credential: new DefaultAzureCredential(),
    credentialScopes: ["https://management.azure.com/.default"]
  }
});

// Add custom policies in specific order
pipeline.addPolicy(logPolicy({ 
  allowedHeaderNames: ["x-ms-request-id"] 
}), { 
  beforePolicies: [serializationPolicyName] 
});

pipeline.addPolicy(retryPolicy({ 
  maxRetries: 3 
}), { 
  afterPolicies: [deserializationPolicyName] 
});

XML Processing Example

import { 
  serializationPolicy,
  deserializationPolicy,
  XML_ATTRKEY,
  XML_CHARKEY 
} from "@azure/core-client";

// XML serialization with attributes
const xmlSerializationPolicy = serializationPolicy({
  stringifyXML: (obj) => {
    return convertToXMLWithAttributes(obj);
  },
  serializerOptions: {
    xml: {
      rootName: "envelope",
      includeRoot: true,
      xmlCharKey: XML_CHARKEY // "_"
    }
  }
});

// XML deserialization with attribute handling
const xmlDeserializationPolicy = deserializationPolicy({
  parseXML: async (xmlString) => {
    return parseXMLWithAttributes(xmlString);
  },
  expectedContentTypes: {
    xml: ["application/xml", "text/xml"]
  },
  serializerOptions: {
    xml: {
      xmlCharKey: XML_CHARKEY,
      includeRoot: false
    }
  }
});

// Custom XML helpers
function convertToXMLWithAttributes(obj: any): string {
  // Handle objects with XML_ATTRKEY for attributes
  // and XML_CHARKEY for text content
  let xml = "<root";
  
  if (obj[XML_ATTRKEY]) {
    for (const [key, value] of Object.entries(obj[XML_ATTRKEY])) {
      xml += ` ${key}="${value}"`;
    }
  }
  
  xml += ">";
  
  if (obj[XML_CHARKEY]) {
    xml += obj[XML_CHARKEY];
  }
  
  xml += "</root>";
  return xml;
}

Policy Error Handling

import { 
  serializationPolicy,
  deserializationPolicy 
} from "@azure/core-client";
import type { PipelinePolicy, PipelineRequest } from "@azure/core-rest-pipeline";

// Custom error handling wrapper for serialization
const errorHandlingSerializationPolicy: PipelinePolicy = {
  name: "errorHandlingSerializationPolicy",
  sendRequest: async (request: PipelineRequest, next) => {
    try {
      // Let serialization policy process the request
      return await next(request);
    } catch (error) {
      if (error.message?.includes("serialization")) {
        console.error("Serialization failed:", error);
        // Add custom error context
        error.context = {
          requestUrl: request.url,
          requestMethod: request.method,
          timestamp: new Date().toISOString()
        };
      }
      throw error;
    }
  }
};

// Wrap standard policies with error handling
const pipeline = createClientPipeline();
pipeline.addPolicy(errorHandlingSerializationPolicy, {
  beforePolicies: [serializationPolicyName]
});

Content Type Handling

import { 
  deserializationPolicy,
  createClientPipeline 
} from "@azure/core-client";

// Advanced content type handling
const pipeline = createClientPipeline({
  deserializationOptions: {
    expectedContentTypes: {
      json: [
        "application/json",
        "application/*+json",
        "text/json"
      ],
      xml: [
        "application/xml",
        "application/*+xml",
        "text/xml",
        "application/soap+xml"
      ]
    },
    serializerOptions: {
      xml: {
        rootName: "response",
        includeRoot: true
      },
      ignoreUnknownProperties: false // Include unknown properties
    }
  }
});

Policy Performance Optimization

import { 
  serializationPolicy,
  deserializationPolicy 
} from "@azure/core-client";

// Optimized policies for high-performance scenarios
const optimizedSerializationPolicy = serializationPolicy({
  serializerOptions: {
    xml: {
      rootName: "data",
      includeRoot: false // Reduce XML overhead
    },
    ignoreUnknownProperties: true // Skip unknown properties for speed
  }
});

const optimizedDeserializationPolicy = deserializationPolicy({
  expectedContentTypes: {
    // Specific content types for faster matching
    json: ["application/json"],
    xml: ["application/xml"]
  },
  serializerOptions: {
    xml: {
      includeRoot: false
    },
    ignoreUnknownProperties: true
  }
});

Policy Integration with ServiceClient

import { 
  ServiceClient,
  createClientPipeline,
  serializationPolicy,
  deserializationPolicy 
} from "@azure/core-client";
import type { OperationSpec } from "@azure/core-client";

class CustomPolicyClient extends ServiceClient {
  constructor(endpoint: string) {
    // Create pipeline with custom policy configuration
    const pipeline = createClientPipeline({
      serializationOptions: {
        serializerOptions: {
          xml: { rootName: "request" }
        }
      },
      deserializationOptions: {
        expectedContentTypes: {
          json: ["application/json"],
          xml: ["application/xml"]
        }
      }
    });
    
    super({ endpoint, pipeline });
  }
  
  async customOperation(data: any): Promise<any> {
    const operationSpec: OperationSpec = {
      httpMethod: "POST",
      path: "/custom",
      contentType: "application/xml",
      serializer: createSerializer({}, true), // XML serializer
      requestBody: {
        parameterPath: "data",
        mapper: {
          type: { name: "Composite" },
          xmlName: "customData",
          modelProperties: {
            value: {
              serializedName: "value",
              xmlName: "value",
              type: { name: "String" }
            }
          }
        }
      },
      responses: {
        200: {
          bodyMapper: {
            type: { name: "Composite" },
            xmlName: "customResponse",
            modelProperties: {
              result: {
                serializedName: "result",
                xmlName: "result",
                type: { name: "String" }
              }
            }
          }
        }
      }
    };
    
    return this.sendOperationRequest({ data }, operationSpec);
  }
}

Policy Lifecycle

Pipeline policies execute in a specific order during request/response processing:

Request Processing Order

  1. Request policies (logging, user agent, etc.)
  2. Authentication policies
  3. Serialization policy (converts objects to HTTP payload)
  4. Transport policy (sends HTTP request)

Response Processing Order

  1. Transport policy (receives HTTP response)
  2. Deserialization policy (converts HTTP payload to objects)
  3. Response policies (logging, custom processing)

Policy Chain Example

// The policy chain for a typical Azure SDK client:
// 1. userAgentPolicy
// 2. logPolicy (request logging)
// 3. bearerTokenAuthenticationPolicy
// 4. serializationPolicy ← converts JS objects to HTTP
// 5. HTTP transport
// 6. deserializationPolicy ← converts HTTP to JS objects
// 7. logPolicy (response logging)
// 8. retryPolicy (if needed)

This modular approach allows for flexible customization while maintaining consistent behavior across all Azure SDK clients.