Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
Andre_Fischer
Product and Topic Expert
Product and Topic Expert
Today I saw a question in SAP Community where the question was raised how to prepare a payload for an OData service that supports creating new entities but where the developer hasn't bothered to implement any GET methods.

First of all this is a very bad style of implementation and I am wondering how that developer has ever tested his or her implementation.

I have to admit that such an implementation can also be found in one of the former SAP Fiori reference apps ...

But since this won't help the developer that has asked this question I thought how to tackle it.

First of all I checked that the payload of a create request can be very simple if you use the json format.

Let's have a look at the GWSAMPLE_BASIC service that lets you create new sample products.

The following request
https://sapes5.sapdevcenter.com/sap/opu/odata/iwbep/GWSAMPLE_BASIC/ProductSet('HT-1000')?$format=json

would provide this response
{
-d: {
-__metadata: {
id: https://sapes5.sapdevcenter.com/sap/opu/odata/iwbep/GWSAMPLE_BASIC/ProductSet('HT-1000')
uri: https://sapes5.sapdevcenter.com/sap/opu/odata/iwbep/GWSAMPLE_BASIC/ProductSet('HT-1000')
type: "GWSAMPLE_BASIC.Product"
etag: "W/"datetime'2020-10-16T02%3A01%3A48.0000000'""
}
ProductID: "HT-1000"
TypeCode: "PR"
Category: "Notebooks"
Name: "Notebook Basic 15"
NameLanguage: "EN"
Description: "Notebook Basic 15 with 2,80 GHz quad core, 15" LCD, 4 GB DDR3 RAM, 500 GB Hard Disc, Windows 8 Pro"
DescriptionLanguage: "EN"
SupplierID: "0100000000"
SupplierName: "SAP"
TaxTarifCode: 1
MeasureUnit: "EA"
WeightMeasure: "4.200"
WeightUnit: "KG"
CurrencyCode: "USD"
Price: "956.00"
Width: "30.000"
Depth: "18.000"
Height: "3.000"
DimUnit: "CM"
CreatedAt: "/Date(1602813708000)/"
ChangedAt: "/Date(1602813708000)/"
-ToSalesOrderLineItems: {
-__deferred: {
uri: https://sapes5.sapdevcenter.com/sap/opu/odata/iwbep/GWSAMPLE_BASIC/ProductSet('HT-1000')/ToSalesOrderLineItems
}
}
-ToSupplier: {
-__deferred: {
uri: https://sapes5.sapdevcenter.com/sap/opu/odata/iwbep/GWSAMPLE_BASIC/ProductSet('HT-1000')/ToSupplier
}
}
}
}

 

A valid payload for a CREATE request does not need all the metadata we find in the response to our GET request.

We can simply send this payload:

 
{
"ProductID" : "HT-XYZ",
"TypeCode" : "PR",
"Category" : "Notebooks",
"Name" : "Notebook Basic 15",
"NameLanguage" : "EN",
"Description" : "Notebook Basic 15 with 2,80 GHz quad core, 15\" LCD, 4 GB DDR3 RAM, 500 GB Hard Disc, Windows 8 Pro",
"DescriptionLanguage" : "EN",
"SupplierID" : "0100000046",
"SupplierName" : "SAP",
"TaxTarifCode" : 1,
"MeasureUnit" : "EA",
"WeightMeasure" : "4.200",
"WeightUnit" : "KG",
"CurrencyCode" : "EUR",
"Price" : "956.00",
"Width" : "30.000",
"Depth" : "18.000",
"Height" : "3.000",
"DimUnit" : "CM"
}

 

and have to provide the following http headers

  • accept with the value application/json

  • X-CSRF-Token which has to be requested first with a GET request that uses the http header the header field X-CSRF-Token with the value Fetch as described in the Online Help.



Please also note the comment from gaurav.karkara3 (see comment section below) not to use a GET request that contains the entity set in URI, but simply the root URL of the service.

The content of the payload, that means the names of the fields can be retrieved from the $metadata document.

https://sapes5.sapdevcenter.com/sap/opu/odata/iwbep/GWSAMPLE_BASIC/$metadata

Here we find the description of the entity type Product.

This contains the field names such as ProductID alongside with their type which is in this case Edm.String with a maximum length of 10 characters.

The only thing now to find out is which fields are mandatory and which not. Some services will for example not need the key to be provided by the consumer but will generate an appropriate key.

This is then, in addition to the cut and paste from the $metadata document, left as an exercise for the developer that wants to consume the service.

 
<EntityType Name="Product" sap:content-version="1">
<Key>
<PropertyRef Name="ProductID"/>
</Key>
<Property Name="ProductID" Type="Edm.String" Nullable="false" MaxLength="10" sap:label="Product ID" sap:updatable="false"/>
<Property Name="TypeCode" Type="Edm.String" Nullable="false" MaxLength="2" sap:label="Type Code"/>
<Property Name="Category" Type="Edm.String" Nullable="false" MaxLength="40" sap:label="Category"/>
<Property Name="Name" Type="Edm.String" Nullable="false" MaxLength="255" sap:label="Product Name" sap:sortable="false" sap:filterable="false"/>
<Property Name="NameLanguage" Type="Edm.String" MaxLength="2" sap:label="Language" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
<Property Name="Description" Type="Edm.String" MaxLength="255" sap:label="Prod.Descrip." sap:sortable="false" sap:filterable="false"/>
<Property Name="DescriptionLanguage" Type="Edm.String" MaxLength="2" sap:label="Language" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
<Property Name="SupplierID" Type="Edm.String" Nullable="false" MaxLength="10" sap:label="Business Partner ID"/>
<Property Name="SupplierName" Type="Edm.String" MaxLength="80" sap:label="Company" sap:creatable="false" sap:updatable="false"/>
<Property Name="TaxTarifCode" Type="Edm.Byte" Nullable="false" sap:label="Tax Tariff Code"/>
<Property Name="MeasureUnit" Type="Edm.String" Nullable="false" MaxLength="3" sap:label="Unit of Measure" sap:semantics="unit-of-measure"/>
<Property Name="WeightMeasure" Type="Edm.Decimal" Precision="13" Scale="3" sap:unit="WeightUnit" sap:label="Weight"/>
<Property Name="WeightUnit" Type="Edm.String" MaxLength="3" sap:label="Unit of Measure" sap:semantics="unit-of-measure"/>
<Property Name="CurrencyCode" Type="Edm.String" Nullable="false" MaxLength="5" sap:label="Currency Code" sap:semantics="currency-code"/>
<Property Name="Price" Type="Edm.Decimal" Precision="16" Scale="3" sap:unit="CurrencyCode" sap:label="Price"/>
<Property Name="Width" Type="Edm.Decimal" Precision="13" Scale="3" sap:unit="DimUnit" sap:label="Dimensions"/>
<Property Name="Depth" Type="Edm.Decimal" Precision="13" Scale="3" sap:unit="DimUnit" sap:label="Dimensions"/>
<Property Name="Height" Type="Edm.Decimal" Precision="13" Scale="3" sap:unit="DimUnit" sap:label="Dimensions"/>
<Property Name="DimUnit" Type="Edm.String" MaxLength="3" sap:label="Dimension Unit" sap:semantics="unit-of-measure"/>
<Property Name="CreatedAt" Type="Edm.DateTime" Precision="7" sap:label="Time Stamp" sap:creatable="false" sap:updatable="false"/>
<Property Name="ChangedAt" Type="Edm.DateTime" Precision="7" ConcurrencyMode="Fixed" sap:label="Time Stamp" sap:creatable="false" sap:updatable="false"/>
<NavigationProperty Name="ToSalesOrderLineItems" Relationship="GWSAMPLE_BASIC.Assoc_Product_SalesOrderLineItems" FromRole="FromRole_Assoc_Product_SalesOrderLineItems" ToRole="ToRole_Assoc_Product_SalesOrderLineItems"/>
<NavigationProperty Name="ToSupplier" Relationship="GWSAMPLE_BASIC.Assoc_BusinessPartner_Products" FromRole="ToRole_Assoc_BusinessPartner_Products" ToRole="FromRole_Assoc_BusinessPartner_Products"/>
</EntityType>

 

 

 

 

 

 

 

 
3 Comments