on 2020 Nov 11 9:11 AM
Hi,
I am trying to implement an endpoint that allows me to upload files from the browser.
Here is a sample fetch request from the client(browser)
const files =event.getParameter('files');
const file= files[0];
const formData =new FormData();
formData.append(file.name,file);
fetch({
url:`/item/upload`,
method:'POST',
body: formData,
})
How do I implement this action in my .cds file.
It looks like this right now (simplified)
service ItemService {
type statusMessageType {
ok : Boolean;
message:String;
status: Integer;
ID:String;
};
action importEnvironment(fileId :String, envId :String, ver :String) returns statusMessageType;
action deleteItem(ID:String) returns statusMessageType;
action addFolder(folderName :String, currentFolderID :String) returns statusMessageType;
action renameItem(sourceID :String, targetID :String) returns statusMessageType;
action upload() returns statusMessageType;
}
How do I 'catch' the `formData` (body) in this `upload()` action as a parameter? And what type should it have? Binary?
Is this possible?
As a workaround I have implemented it as a normal express endpoint and it works in development.
But when I deploy my app to cloud foundry all my express implemented endpoints such as the following are not found and I get a 404 for them.
app.post('/upload');
app.get('/getItems');
Is this expected since we are not 'supposed' to do it like this?
Request clarification before answering.
Please check out the example CAP Media Handling or the one in cloud-cap-samples
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Yes I did initially.
But I don't want the file to be saved in the db.
In fact, I am not planning on using a db at all.
I want to just save the file to amazon s3.
For s3 examples, I also checked https://github.com/pdominique/cap-media-node .
But even here I first need to send a POST request (which adds an entry to the db) and then I have to send a PUT request to actually 'upload' the file to s3.
I don't wish to send a POST request first as I don't want to have a db at all.
Is this possible?
Just one POST request with the body containing the file so I can upload it to s3 ?
I find the s3 object by id.
I am using the 'aws-sdk' package.
To get all the objects i simply use s3.listObjects()
And to get a particular object(in this case a file), i simply generate a signed URL with s3.getSignedUrl().
Getting the objects from s3 is perfectly working and not a problem. And for this I really don't need any reference in a db.
I don't have any problem with 2 requests. My only question is if there is a way to send files from browser to the cds backend without saving a reference in the db first? I just want to get the file and send it to s3...
If you want to follow the OData standard: No.
You can still implement your custom handlers in express.
If you want to implement a custom express handler, here's an example: https://github.com/SAP-samples/hana-opensap-cloud-2020/blob/main/srv/routes/excel.js
This video might help -> https://youtu.be/dmeRX9n6uQo
Hi @gregorw ,
I'm trying to have an upload action in my cds. Trying something like this
action uploadExcelFile(file : LargeBinary @Core.MediaType: 'text/csv');
and defined a handler in the service layer (JAVA). But whenever I try to hit this action using postman, I get the below error
Taking your example as a reference, the upload action would need to have a parameter defined as type Binary or LargeBinary. Then, you would need a custom event handler for the action (https://cap.cloud.sap/docs/guides/providing-services#custom-event-handlers). The file would be accessible to you through the req argument of the handler, as one of its parameters (https://cap.cloud.sap/docs/node.js/events#params).
So a hypothetical custom event handler for your action "upload" with argument "file" of type LargeBinary would look like this:
this.on ('upload', (req)=>{
const file = req.params.file;
//file upload to s3
})
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@danilo_apicella1 I do have the custom handler written in my code. But it is not triggered on the post call, I get the error before that itself.
I'm using CAP Java.
User | Count |
---|---|
61 | |
7 | |
7 | |
6 | |
6 | |
5 | |
4 | |
4 | |
3 | |
3 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.