cancel
Showing results for 
Search instead for 
Did you mean: 

Creating (POST) an entity via a navigation property?

MattHarding
Active Contributor
0 Kudos

Hi All,

Let's say we have a model that has an Employees entityset, and for a given employee, you can navigate to a CurrentCarParkingSpot entity (it's an example not reality).

e.g. Employees('00123456')/CurrentCarParkingSpot would pull up the current CarParkingSpot against the Employee.


Now if the employee didn't have a CarParkingSpot, and I want to create a new CarParkingSpot for this employee, you would think I could POST a standard CarParkingSpot payload to Employees('00123456')/CurrentCarParkingSpot and it should create a new CarParkingSpot against employee (assuming I get the employee key in the GW code). However, when I try this, the framework doesn't even call my code, and it's almost like Gateway does not support creation via a navigation property. PUT works, just not POST.

Note - If I post the same payload directly to /CarParkingSpots, it works fine.

e.g. The payload looks like:


<?xml version="1.0" encoding="utf-8"?>

<entry xml:base="http://server.local/sap/opu/odata/sap/ZEXAMPLE/" xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">

  <id>http://server.local/sap/opu/odata/sap/ZEXAMPLE/CarParkingSpot</id>

  <title type="text">CarParkingSpot</title>

  <category term="ZEXAMPLE.CarParkingSpot" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>

  <content type="application/xml">

   <m:properties>

   </m:properties>

  </content>

</entry>

So the key question: Is creation (POST) via Navigation Properties supported in GW, and if it is, do you need to alter the payload at all (note - I've tried changing the id and text above to align with navigation property)?

FYI - I've been testing via Gateway Client, and getting successful creation by using "Use as request" from an existing specific Employees('another id')/CurrentCarParkingSpot and removing all id's in the POST payload.

Thanks,

Matt

Accepted Solutions (1)

Accepted Solutions (1)

MattHarding
Active Contributor
0 Kudos

Apparently POST only makes sense to Collections from a RESTFul perspective hence even though this is a 0..1 relationship, if it doesn't exist, you can't "POST" into the empty relationship. A suggestion was the PUT may work, but you would need to know everything about the entity and since you're unlikely to know the key, this doesn't make sense either.

So solution is always to go via EntitySets, and to provide the Employee Id in the payload of that POST.

Thanks to those who contacted me outside of Social Media.

Cheers,

Matt

Former Member
0 Kudos

Hi Matt,

This is a limitation of GW, not OData. If you peruse some non-SAP OData resources you will find mention of posting to navigations.

The OData 4.0 spec states:

To create an entity in a collection, the client sends a POST request to that collection's URL. The POST body MUST contain a single valid entity representation.

An entity may also be created as the result of an Upsert operation.

If the target URL for the collection is a navigation link, the new entity is automatically linked to the entity containing the navigation link.

The GW framework requires you to POST to a canonical URI, i.e. unnavigated direct address.

In my view navigated POST should be supported by GW otherwise it imposes unrealistic design issues, e.g. you now have to include the key of a parent into a child entity to satisfy your requirement.

There are other reasons why it's desirable to POST to the navigation endpoint.

1 - As the navigation points get longer, the need to add more key properties to the endpoint arises:

e.g. for myservice/entityset1(1)/entityset2(2)/siblings(3)/classifications, the classifications entity needs three properties that probably aren't anything like the canonical URI.

This will, at code level mean there are going to be divergences in the access methods that don't need to be present.

2 - The canonical URI may not be addressable. In the above example, classifications is not likely to be something that has any context outside of a navigated path,so a canonical URI for posting one cannot be established.

I don't know why SAP haven't allowed this as the runtime components certainly have the potential to expose the navigation context if the POST request was allowed in.

In the interim, it might be possible design a model that would allow pseudo-navigation posting by using a batched request, so I may have a look into this.

Regards

Ron.

Former Member
0 Kudos

Hi Matt,

I've been back to check on this and you should be able to POST to the navigation endpoint in GW, with some caveats.

1 - It wasn't supported in earlier versions of GW. On the system I tested with, we have IW_BEP at 200 SP 6 and IW_FND at 250 SP6. If you have a t least these levels it should work.

2 - Expanding on my reply above, although post to navigation works, it is limited in the GW implementation. The request does not transfer the navigation path details, only the entityset source and target. That means that the creation of entities this way can only be done reliably when the navigation to the endpoint entity can only come from one place. Other navigations may alter the context and the rules for creation.

I think that SAP could fix this with a bit of tweaking because the navigation object is available, but dropped.

3 - I'm pretty sure this will only work for two levels of navigation as the request keytab contains the immediate 'parent' key so that you can use it to qualify the data in the 'child' payload.

Lastly, it may not be working for you because you have emptied the payload content entirely. When using 'Use as request' did you strip all element tags or just nullify them?

Cheers

Ron.

MattHarding
Active Contributor
0 Kudos

Thanks for the detailed responses Ron. In short, it looks like it's limited to just Post on entitysets which is fair enough, and where I have an entity with attachments navigation property, I can post a new attachment to that entity without issue (except for the obscure ContentType Design time code you have to write that had me stuck for a little while - but that's another story). But when I post to this, I do get access to the parent keys automatically which makes adding the attachment easy. Luckily, I don't have more than 1 level in this scenario.

But for the 0..1 relationship, it is effectively an Entity and not an EntitySet so not supported. I can't tell from your comment whether Post should be supported in this scenario in 4.0 since realistically you would need to check the Entity is blank first in order to Post; but for now, I'm just putting in key information into the payload on the root EntitySet. Oh well.

In answer to your question, I just stripped off elements, to effectively nullify them but it was effectively a pretend scenario regardless...or is it my amazing Parking Lot Employee Fiori like App that I'm going to release! and make millions from 😉

Cheers,

Matt

Answers (0)