-
Notifications
You must be signed in to change notification settings - Fork 52
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
UpdateRequestBuilder sending an empty payload as part of a batch/changeset request #4673
Comments
Hey @seeroush thank's for reaching out. The usage of the SDK does look correct, and the empty patch request is rather suspicious. Are you certain the |
Hi @tomfrenken, yes. I validated that the values were non-empty via a debugger. I'm currently having to work around the issue by explicitly setting the payload like so:
Do the handling of the out-of-the-box features depend on the destination being configured a certain way? One thing I should clarify is that I am hitting an on-premesis SAP instance and am not connecting through an SAP cloud proxy. Could that have something to do with the strange behavior around CSRF/ETag fetching? |
Hmm, let's try a few things.
We can see in the logs that the entity's If you don't set the
and
if this doesn't work, the target system is likely the cause, meaning it doesn't follow the usual default.
|
Thanks, Tom! The solution I currently landed with does look similar to what you've outlined. Because I'm doing batch operations, I had to manually build out the middleware as you suggested to extract both CSRF and etag tokens. The psuedocode looks something like: // Fetch CSRF token and cookie via middleware on a GET request
const {token, cookies} = getCsrfToken();
// entries are returned with a single HTTP batch request
// etags are returned as a map<document_id, etag>. The etag identifiers are plucked from response.body.d.__metadata.etag
const {entries, etags} = await fetchViaBatch(myEntryIdentifiers);
// Build changeset request for all entries which includes setEditable, updateEntryValue, setReadOnly
const changesets = entries.map((entry) => getChangeSet(entry))
// Perform batch update request with all changesets
const batchRequest = batch(changesets);
const batchReqId = batchRequest.build().config.boundary;
const responses = await batchRequest.addCustomHeaders({
'x-csrf-token': resp.csrfToken,
// Not entirely sure why, but I had to manually fetch the boundary value and set the top-level header for it to work.
'content-type': `multipart/mixed;boundary=${batchReqId}`,
'cookie: `${resp.cookie};`,
}).execute({ destinationName: 'DESTINATION' }); While this works in practice for a single SAP instance, I'm trying to identify exceptions so that when we start interfacing with more than one SAP instance, the code will be as portable as possible. I suppose I'm just having a hard time understanding what conditions (destination configuration, request building, etc...) are ideal so that I don't need to manually fetch and build my requests. It sounds like the client is supposed to handle it, but I'm not sure what the exceptions/conditions are that requires a custom solution. I will talk to the team to see if it's possible for us to use a cloud connector for our test SAP deployment. |
The issues you are currently facing should be unrelated to the cloud connector. Can you share for which service you've generated the client? Ideally the target system's endpoint returns the csrf token so you don't have to build your own middleware and create the csrf token & cookie headers. I'm surprised you had to set
|
The name of the service is FAC_FINANCIAL_DOCUMENT_SRV_01. I've attached the .edmx file (as a .txt) with the redacted domain URI (fake.domain.com). Let me know if that helps. |
Alright, I've generated a client and tried to replicate the issue, however, for me, the correct payload was created. My current assumption is, that the remote state has been updated in between your requests, which would lead to an empty payload, as the remote state already contains the change. Can you verify what the remote state contains at runtime?
here you can check if the entry already contained the desired change. |
Alternatively, you can also try to use a |
Thanks Tom! I'll look into the remoteState field to see what its contents are prior to the update batch request. I'm going to be out-of-office for the next week, so there'll be a bit of delay in the response. I appreciate the feedback and all your effort in helping out. |
I'm not sure if this is a bug, or possibly the way I am utilizing the generated OData v2 client. I am attempting to perform a batch request on a particular API, and noticed that the
PATCH
method is not providing any payload in the changeset body. From the documentation, I'd expect the assignment of the paymentTerms and cashDiscountAmount to be in the payload based on the following statement:If anyone could guide me on how to properly use the changeset/batch API in addition to updating an entity, it'd be appreciated. I also noticed that
etag
andcsrf
functionality of the client was not automatically handled, so I had to manually add the appropriate headers to get to this point. I kept that out of the paired-down sample below, but if CSRF handling should be automatic, guidance around how to get the auto-generated clients to handle it would be appreciated as well. The documentation led me to believe it's automatic.Here's a sample of how I'm using a combination of
batch
andchangeset
to perform the request.Dependencies:
Code:
I am getting 415 responses from the server, so I added some middleware to output the request body to console, and noticed that the
PATCH
request body is set to{}
when I would've expected it to be:Thanks in advance!
The text was updated successfully, but these errors were encountered: