codejenn
10/02/2023, 7:59 PMcody
10/02/2023, 8:38 PMcreateBinary method posts the file contents to the https://api.medplum.com/fhir/R4/Binary endpoint
The method is a pretty simple wrapper around our HTTP POST helper:
createBinary(
data: BinarySource,
filename: string | undefined,
contentType: string,
onProgress?: (e: ProgressEvent) => void
): Promise<Binary> {
const url = this.fhirUrl('Binary');
if (filename) {
url.searchParams.set('_filename', filename);
}
if (onProgress) {
return this.uploadwithProgress(url, data, contentType, onProgress);
} else {
return this.post(url, data, contentType);
}
}
The createAttachment method is purely a convenience helper, which creates the Binary via HTTP call, and then creates an in-memory Attachment populated with the Binary url:
async createAttachment(
data: BinarySource,
filename: string | undefined,
contentType: string,
onProgress?: (e: ProgressEvent) => void
): Promise<Attachment> {
const binary = await this.createBinary(data, filename, contentType, onProgress);
return {
contentType,
url: binary.url,
title: filename,
};
}
Note that in FHIR, a Binary is an actual "resource type" (i.e., it lives in the database), whereas an Attachment is a JSON data type, and only exists inside other resources.
For example, if I want to create a FHIR Media
1. First create the Binary via API request
2. Create an Attachment in memory as part of the Media
3. Create the Media via API request
A simplified FHIR Media looks something like this:
{
"resourceType": "Media",
"content": {
"contentType": "image/jpeg",
"url": "Binary/MY_BINARY_ID",
"title": "picture.jpg"
}
}d_vincent
10/02/2023, 8:54 PMmedplum.post method that createBinary is wrapping.
We received a successful response with an included URL, and we see the Binary as being created in our Medplum app, but under "Data" we are seeing "base64Binary not implemented" - any ideas?reshma
10/02/2023, 11:23 PMd_vincent
10/03/2023, 12:22 AMapp.medplum.com project under Binary resources. Here are a couple of screenshots of what I'm seeing. It's probably worth noting that there is no URL listed here, but I did receive a URL in the post responsereshma
10/03/2023, 4:39 PMd_vincent
10/03/2023, 5:20 PMCommunication in our messaging application, here is the code we are using to create this resource:
const uploadAttachment = async (attachment: Attachment) => {
const url = MedplumBaseUrl + 'fhir/R4/binary';
medplum?.setAccessToken(medplumToken);
const attachmentUploadResponse = await medplum?.post(url, attachment.data, attachment.contentType ?? 'application/octet-stream');
return attachmentUploadResponse;
}
We would like to then use the attachmentUploadResponse values to build the contentAttachment of a Communication payload.
In the above example, attachment.data represents the Base64 encoded string of the image itselfreshma
10/03/2023, 10:58 PMd_vincent
10/04/2023, 8:08 PMconst uploadAttachment = async (attachment: Attachment) => {
if (!attachment.data) return;
const url = MedplumBaseUrl + 'fhir/R4/binary';
const attachmentUploadResponse = await fetch(url, {
method: 'POST',
body: attachment.data,//this is the base64 string
headers: {
'Content-Type':
attachment.contentType ?? 'application/octet-stream',
Authorization: 'Basic ' + authHeader,
},
});
return attachmentUploadResponse;
}
Response:
{
"_bodyBlob": {
"_data": {
"__collector": [
"Object"
],
"blobId": "FEFFA356-2257-4B59-A6A6-627E82AAB8CD",
"name": "binary.json",
"offset": 0,
"size": 715,
"type": "application/json"
}
},
"_bodyInit": {
"_data": {
"__collector": [
"Object"
],
"blobId": "FEFFA356-2257-4B59-A6A6-627E82AAB8CD",
"name": "binary.json",
"offset": 0,
"size": 715,
"type": "application/json"
}
},
"bodyUsed": false,
"headers": {
"map": {
"cache-control": "no-store, no-cache, must-revalidate",
"content-length": "715",
"content-security-policy": "default-src 'none'; base-uri 'none'; form-action 'none'; frame-ancestors 'none';",
"content-type": "application/json; charset=utf-8",
"date": "Wed, 04 Oct 2023 19:53:54 GMT",
"pragma": "no-cache",
"referrer-policy": "no-referrer",
"strict-transport-security": "max-age=63072000; includeSubDomains; preload",
"vary": "Accept-Encoding",
"x-content-type-options": "nosniff",
"x-frame-options": "DENY",
"x-xss-protection": "1; mode=block"
}
},
"ok": true,
"status": 201,
"statusText": "",
"type": "default",
"url": "https://api.medplum.com/fhir/R4/binary"
}reshma
10/04/2023, 8:19 PMd_vincent
10/04/2023, 8:25 PMfetch and providing the binary data directly - I will perform the curl and report backd_vincent
10/04/2023, 8:47 PMd_vincent
10/04/2023, 8:58 PMreshma
10/04/2023, 9:11 PMd_vincent
10/04/2023, 9:13 PMurl='Binary/<id>', though it appears there is still no image data being associatedd_vincent
10/04/2023, 9:15 PMreshma
10/04/2023, 9:29 PMd_vincent
10/04/2023, 11:07 PMBuffer.from('base64') before adding it to the post body. Here is the final working solution in javascript:
const uploadAttachment = async (attachment: Attachment) => {
if (!attachment.data) return;
const url = MedplumBaseUrl + 'fhir/R4/Binary';
const base64Data = Buffer.from(attachment.data, 'base64')
const attachmentUploadResponse = await medplum?.post(url, base64Data, attachment.contentType ?? 'application/octet-stream');
return attachmentUploadResponse;
}reshma
10/04/2023, 11:08 PMd_vincent
10/04/2023, 11:09 PM