How To Create ContentHeader API Variable - SuiteEngine/APIEngine GitHub Wiki
This section describes how to add content headers to an HTTP request using an API Variable. Content headers are headers that are applied to the HTTP request body/content rather than the general request headers. Common content headers include Content-Disposition, Content-Language, Content-Encoding, and custom content-specific headers required by certain APIs.
Before we begin, it's important to understand the difference between Request Headers and Content Headers:
-
Request Headers (Variable Scope = Header) are applied to the overall HTTP request. These include headers like
Authorization,Accept,User-Agent, etc. -
Content Headers (Variable Scope = Content Header) are applied specifically to the HTTP request body/content. These include headers like
Content-Disposition,Content-Language, or custom headers that certain APIs require on the content portion of the request.
Content headers are particularly useful when:
- Uploading files and need to specify
Content-Dispositionwith filename metadata - Working with APIs that require specific content-level metadata
- Specifying content language or encoding preferences on the request body
For this tutorial, we will create an API Function that uploads a file to a document storage API. The API requires a Content-Disposition header on the request content to specify the filename. Our goal is to set up:
Content-Disposition: attachment; filename="invoice-12345.pdf"
Where 12345 is dynamically populated from a Business Central record.
Let's start by creating a simple static content header. From the API Functions list page for your API Set, navigate to the API Variables for your function.
Add a new API Variable with the following field values:
-
Auto Build Sequence (PK1) - An integer value that determines the processing order of content headers. For this example, enter: 10
-
Variable Scope (PK2) - Select Content Header to indicate this variable will be added to the HTTP request content headers.
-
Name (PK3) - Enter the name of the content header. For this example, enter: Content-Disposition
-
Variable Value Type - For content headers, use Key Value Text since we want a header in the format
HeaderName: HeaderValue. Select: Key Value Text -
Value Processing Type - Since we want a fixed value for now, select: Static
-
Static Value - Enter the static header value: attachment; filename="document.pdf"
-
API Name Processing - Select: Static (the header name will always be "Content-Disposition")
-
Static Name - This should auto-populate with the Name field value: Content-Disposition
When you execute this API Function, the API Engine will add the Content-Disposition: attachment; filename="document.pdf" header to your HTTP request content.
Now let's create a more practical example where the filename includes a dynamic value from a Business Central record. We'll use the Sales Invoice Header table to include the invoice number in the filename.
Add a new API Variable with the following field values:
-
Auto Build Sequence (PK1) - Enter: 10
-
Variable Scope (PK2) - Select: Content Header
-
Name (PK3) - Enter: Content-Disposition
-
Variable Value Type - Select: Key Value Text
-
Value Processing Type - For dynamic values from a parameter record, select: Parameter Record
-
Variable Value Null Behavior - Select: Do not Include - This ensures the header is only added when we have a valid value.
-
Value Table No. - Enter the table number for Sales Invoice Header: 112
-
Value Field No. - Enter the field number for the No. field: 3
With this configuration, the API Engine will look for a Sales Invoice Header record in the API Message parameters and use the invoice number to construct the header value.
For more complex scenarios where you need to format the header value (e.g., attachment; filename="invoice-{No}.pdf"), you can use a custom Value Processing codeunit that implements the SENAPIValueProcessing.Interface.
Here's an example of how to implement a custom value processor for the Content-Disposition header:
codeunit 50100 "Content Disposition Value Proc" implements SENAPIValueProcessing
{
procedure GetAPIVariableValue(var SENAPIVariable: Record "SENAPI Variable"; var SENAPIMessage: Record "SENAPI Message"): Text
var
SalesInvoiceHeader: Record "Sales Invoice Header";
SENAPIParameter: Record "SENAPI Parameter";
RecRef: RecordRef;
begin
// Find the Sales Invoice Header parameter using the standard API Parameter key structure
// Key structure: Parameter Type = Record, Record = API Message RecordId, Key = Table No., Key Index = 0
if SENAPIParameter.Get(
SENAPIParameter."Parameter Type"::Record,
SENAPIMessage.RecordId,
Database::"Sales Invoice Header",
0) then begin
// Get the actual record from the Table Record Value field
RecRef.Open(Database::"Sales Invoice Header");
if RecRef.Get(SENAPIParameter."Table Record Value") then begin
RecRef.SetTable(SalesInvoiceHeader);
exit(StrSubstNo('attachment; filename="invoice-%1.pdf"', SalesInvoiceHeader."No."));
end;
end;
exit('');
end;
}To use this custom processor:
- Register your codeunit in the SENAPIValueProcessingType enum extension
- Set the Value Processing Type on your API Variable to your custom type
- Optionally set the Value Processing Function Name if your implementation supports multiple functions
Here's an example of how to execute an API Function with a Content Header that uses a parameter record:
procedure UploadInvoiceDocument(SalesInvoiceHeader: Record "Sales Invoice Header")
var
SENAPIMessage: Record "SENAPI Message";
SENAPIMessageManagement: Codeunit SENAPIMessageManagement;
begin
// Create the API Message for the upload function
SENAPIMessage := SENAPIMessageManagement.CreateNewAPIMessage('DOCSTORAGE', 'UPLOAD_INVOICE');
// Add the Sales Invoice Header record as a parameter
SENAPIMessageManagement.AddNewRecordParamterToAPIMessage(SENAPIMessage, SalesInvoiceHeader.RecordId);
// Execute the API Message
SENAPIMessageManagement.ExecuteAPIMessage(SENAPIMessage);
end;The API Engine processes content headers after initializing the HTTP request but before attaching authorization. The AddContentHeaderVariables procedure in SENAPI Request Management codeunit handles this:
- Checks if the API Function has any Content Header variables with key-value pair types
- Retrieves the HTTP content headers from the request message
- For each Content Header variable, evaluates the value using the configured Value Processing Type
- Removes any existing header with the same name (to allow overriding default headers)
- Adds the header to the content if the value is not empty
Content Header variables support the following Variable Value Types:
- Key Value Text - The most common type for content headers
- Key Value Decimal - For numeric header values
- Key Value Integer - For integer header values
- Key Value Boolean - For boolean header values
If you need to override a default content header (like Content-Type which is typically set automatically), create a Content Header variable with that header name. The API Engine will remove the existing header before adding your custom value.