Attachment Objects
Overview
In this chapter, you will add attachment objects to your Workday Extend app. With attachments, users can upload file data and images to your app.
Objectives
By the end of this chapter, you will be able to:
- Create an attachment object in App Builder.
- Add the fileUploader widget to a PMD file.
- Use onMultiPartSend to submit new attachment objects via the REST API.
- Display attachment images in a PMD file.
Attachment Objects
You author attachment objects in JSON. They allow you to store file data and images.
When you create an attachment object, Workday automatically generates the following fields to associate file data with instances of the attachment object:
- file: Store the attached file or image.
- fileName: Derived from properties of the attachment object data. You cannot write to this field, but you can retrieve data using GET.
- fileLength: Write to this field using PUT or POST.
- contentType: Derived from properties of the attachment object data. You cannot write to this field, but you can retrieve data using GET.
You can define additional fields for the attachment object, but your contentType on the POST/PUT must be defined as
multipart/form-data
.Important: The order of your data matters. If JSON data is passed after the file data, you will receive a 500 error.
Limitations
Workday is not a document management system.
The attachment object component and Workday support the following:
- Basic signature capability against documents.
- Collecting documents from workers.
- Distributing documents to workers.
- Securing documents using contextual and segment-based security.
- Storing company-related documents used for distribution.
- Storing supporting documents against many other Workday objects.
This table displays attachment object limitations.
Description | Limit |
|---|---|
Number of instances | 10 million per tenant
Note : This number counts all Extend business object and attachment instances, excluding deleted or purged instances. |
Maximum size of attachment | 10 MB |
The fileUploader widget only supports POST operations, regardless of the defined HTTP method in the
outBoundEndPoint
. If you need to update an attachment, we recommend you delete the file first and then recreate it.Design Considerations
If you are looking at including attachment objects in your app, consider the following:
- How will the user consume or load the attachments?
- How many attachment instances will you need/require?
- Will the attachments be images in your app?
- Will each user request leverage an attachment or require multiple attachments?
All of these will impact the performance of your app and may require proactive monitoring.
Users must download all files, except for PDFs, to their machine in order to view them. To make PDFs available for in-browser viewing, you must set the mime type attribute.
Attachment Object POST APIs
When you create a model attachment for your app, Workday Extend automatically creates REST endpoints that you can use to access and modify attachment instances. Two of the POST endpoints are:
POST Endpoint
| Description |
|---|---|
/{defaultCollection} | Create exactly one new model attachment instance |
/{defaultCollection}Collection | Create one or more model attachment instances |
For example, imagine you created a model attachment called Passport, with a default collection set to
passports
. The endpoints that Extend creates would be:- POST /passports
- POST /passportsCollection
File Uploader Widget
The fileUploader widget enables a user to upload or download files.
You can use the fileUploader widget on:
- An edit page to display an Upload button (compact) or a drag-and-drop area for the user to select the files to upload. When the user clicks OK, the page submits the outbound endpoint with the selected files.
- A view page to display a list of file attachments from an endpoint or a list of file URLs. The fileUploader tag containsfileUploaderRow, which displays each attachment.
As you use fileUploader, consider:
- The maximum number of files you can upload is 5.
- The maximum file size is 10 MB. Therefore, the total size limit on the fileUploader is 50 MB. (To override the default maximum file size, set themaxFileSizeattribute to a number of bytes between 1 and 10,485,760.)
- The fileUploader supports only POST endpoints for submitting file attachments.
The following table lists some of the available attributes on the fileUploader widget:
Attribute | Data Type
| Description
|
|---|---|---|
fileTypes | String | Indicates the file types that the file upload widget supports.
By default, the fileUploader allows these file types:
|
maxFileSize | Number | The maximum file size that the fileUploader widget allows. The default is 10 MB or 10,485,760 bytes (binary).
To override the default maximum file size, set maxFileSize to a number of bytes between 1 and 10,485,760. You can also use a script that returns the maximum file size.
Note : You can only dynamically set maxFileSize upon page load. |
metadata | Map | Describes the file metadata for a multipart request.
If you use the fileUploader with the attachment object collection endpoint, you must specify the metadata attribute whether or not you need to send the file metadata. If the attachment object doesn't contain metadata fields, specify an empty map: "metadata": "<% { : } %>" . |
singular | Boolean | If true, restrict the user to upload only 1 file. The default value is false. |
valueOutBinding | String | The name of the outbound endpoint to submit with the file attachments. |
valueOutBinding
The
valueOutBinding
attribute enables you to bind tag values to outbound fields in the JSON request body that the page submits to an outbound endpoint. In general, bind the widget value to an outbound field using this string format in the widget's valueOutBinding
attribute:outboundEndpointName.fieldPath
The
fieldPath
specifies the field in the JSON request body. Specifying the fieldPath
can be tricky if the JSON request body contains lists and multiple field levels.For more examples, refer to the Developer Documentation: Reference: valueOutBinding Samples.
onMultiPartSend
Sometimes sending data requires your data to be sent with a multipart request body. This is done with a series of form-data parts separated by MIME boundaries. A common use case for multipart data is submitting data with attachments.
Using an endpoint's
onMultiPartSend
event handler allows you to manipulate the JSON data of the multipart request before sending it to the outbound endpoint.The
onMultiPartSend
event triggers just before sending data to a multipart outbound endpoint, enabling you to modify the JSON parts of a multipart request, such as file metadata.The
onMultiPartSend
event triggers when at least 1 widget specifies the valueOutBinding
attribute with a form-data part. The valueOutBinding
for a multipart endpoint uses either format:- <outboundEndpointName>:<formDataName>(The valueOutBinding format on a fileUploader)
- <outboundEndpointName>:<formDataName>:<jsonFieldName>(The valueOutBinding format on any other widget)
The onMultiPartSend event applies only to outboundEndPoints that:
- Are multipart endpoints.
- Use the POST or PUT methods.
Your
onMultiPartSend
event handler should manipulate and return self.data
, which is a map containing the JSON parts of the multipart request.Example File Uploader with onMultiPartSend
In this example, the model definition of the attachment object contains this
defaultCollection
and metadata
fields:{ ... "defaultCollection": { "name": "myAttachments", "label": "My Attachments" }, "fields": [ { "id": 1, "name": "fileDescription", "label": "File Description", "type": "TEXT" }, { "id": 2, "name": "uploadedBy", "type": "SINGLE_INSTANCE", "label": "Uploaded By", "target": "WORKER", "isPurgeable": true }, { "id": 3, "name": "uploadedDate", "type": "DATE", "label": "Uploaded Date", "precision": "DAY" } ] }
This sample fileUploader uses the
metadata
attribute to specify the uploadedBy
and uploadedDate
metadata fields of myAttachments:{ "name": "postAttachment", "url": "myAttachmentsCollection", "authType": "sso", "baseUrlType": "app", "onMultiPartSend": "<% // Iterate through myAttachments[] to modify the metadata. for (var file : self.data.metadata.myAttachments) { // Update fields. file.uploadedBy.id = pageVariables.fileCurator; file.uploadedDate = pageVariables.fileEffectiveDate; // Add a field with dynamic widget data. file.fileDescription = descriptionTextWidget.value; } self.data; %>" }
This snippet displays the response from the attachment object collection endpoint:
{ "myAttachments": [ { "id": "5cfbd418b79c90001f45c637d0920002", "descriptor": "dogCat2.jpg", "fileName": "dogCat2.jpg", "contentType": { "descriptor": "image/jpeg - mime_image", "id": "d9ae5d84446c11de98360015c5e6daf6" }, "fileLength": 8413, "fileDescription": "Dog and cat buddies", "uploadedBy": { "descriptor": "Teresa Serrano", "id": "26c439a5deed4a7dbab76709e0d2d2ca" }, "uploadedDate": "2022-09-01" }, { "id": "5cfbd418b79c90001f45c637d0920001", "descriptor": "dogCat1.jpg", "fileLength": 45577, "fileName": "dogCat1.jpg", "contentType": { "descriptor": "image/jpeg - mime_image", "id": "d9ae5d84446c11de98360015c5e6daf6" }, "uploadedBy": { "descriptor": "Teresa Serrano", "id": "26c439a5deed4a7dbab76709e0d2d2ca" }, "uploadedDate": "2022-09-01", "fileDescription": "Dog and cat buddies" } ] }
Attachment Object GET APIs
When you create a model attachment for your app, Workday Extend automatically creates the following GET endpoints:
GET Endpoint
| Description |
|---|---|
GET /{defaultCollection}
| Get metadata for all attachment instances in the collection. |
GET /{defaultCollections}/{id}
| (No headers) Get attachment file with the specified ID.
(Accept: application/json) Get attachment metadata for the specified instance. |