Skip to content

Commit f041e27

Browse files
committed
Add Single (Inline) Attachments section to README
1 parent 4cb1e07 commit f041e27

1 file changed

Lines changed: 81 additions & 0 deletions

File tree

README.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ It supports the [AWS, Azure, and Google object stores](storage-targets/cds-featu
1818
* [Usage](#usage)
1919
* [MVN Setup](#mvn-setup)
2020
* [Changes in the CDS Models and for the UI](#changes-in-the-cds-models-and-for-the-UI)
21+
* [Single (Inline) Attachments](#single-inline-attachments)
2122
* [Try the Bookshop Sample](#try-the-bookshop-sample)
2223
* [Storage Targets](#storage-targets)
2324
* [Malware Scanner](#malware-scanner)
@@ -115,6 +116,86 @@ annotate service.Incidents with @(
115116

116117
The UI Facet can also be added directly after other UI Facets in a `cds` file in the `app` folder.
117118

119+
### Single (Inline) Attachments
120+
121+
In addition to the composition-based `Attachments` aspect (which supports multiple files), CDS provides the `Attachment` type for **single-file** attachment fields directly on an entity. This is useful when an entity needs exactly one file, for example a profile icon or a cover image.
122+
123+
```cds
124+
using { sap.attachments.Attachment } from 'com.sap.cds/cds-feature-attachments';
125+
126+
entity Books {
127+
key ID : UUID;
128+
title : String;
129+
profileIcon : Attachment;
130+
coverImage : Attachment;
131+
}
132+
```
133+
134+
CDS flattens inline attachment fields onto the parent entity. For example, `profileIcon : Attachment` generates the following columns on the `Books` table:
135+
136+
- `profileIcon_content` (LargeBinary)
137+
- `profileIcon_mimeType` (String)
138+
- `profileIcon_fileName` (String)
139+
- `profileIcon_contentId` (String)
140+
- `profileIcon_status` (StatusCode)
141+
- `profileIcon_scannedAt` (Timestamp)
142+
143+
All plugin features: malware scanning, status tracking, storage targets, maximum file size, and MIME type validation work the same way for inline attachments as for composition-based attachments.
144+
145+
#### UI Annotations for Inline Attachments
146+
147+
To display inline attachments in a Fiori Elements UI, use a `FieldGroup` referencing the flattened field names:
148+
149+
```cds
150+
annotate AdminService.Books with @(UI: {
151+
Facets: [
152+
// ... other facets ...
153+
{
154+
$Type : 'UI.ReferenceFacet',
155+
Label : 'Profile Icon',
156+
Target: '@UI.FieldGroup#ProfileIcon'
157+
}
158+
],
159+
FieldGroup #ProfileIcon: {Data: [
160+
{Value: profileIcon_content},
161+
{Value: profileIcon_status}
162+
]}
163+
});
164+
```
165+
166+
> [!Note]
167+
> For inline attachments, the `content` field is annotated with `@Core.MediaType: 'application/octet-stream'` (a static value) instead of a path reference to the `mimeType` field. This is because CDS flattening rewrites `content` to `profileIcon_content` but does **not** rewrite path references like `mimeType` to `profileIcon_mimeType`, which would result in a broken reference. Static annotations propagate correctly through CDS flattening.
168+
169+
#### Inline Attachments on Composition Children
170+
171+
Inline attachments also work on entities that are composition children. For example, if `Items` is a composition of `Orders`, you can add an inline attachment field to `Items`:
172+
173+
```cds
174+
entity Orders {
175+
key ID : UUID;
176+
items : Composition of many Items;
177+
}
178+
entity Items {
179+
key ID : UUID;
180+
title : String;
181+
receipt : Attachment;
182+
}
183+
```
184+
185+
The plugin automatically discovers inline attachment fields at any level of the composition tree.
186+
187+
#### Combining Inline and Composition-Based Attachments
188+
189+
An entity can use both inline single attachments and composition-based multiple attachments simultaneously:
190+
191+
```cds
192+
entity Books {
193+
key ID : UUID;
194+
profileIcon : Attachment; // single file
195+
attachments : Composition of many Attachments; // multiple files
196+
}
197+
```
198+
118199
### Try the Bookshop Sample
119200

120201
The easiest way to get started is with the included [bookshop sample](samples/bookshop/):

0 commit comments

Comments
 (0)