Skip to Content
Technical Articles
Author's profile photo Andre Fischer

How to prepare a payload for an OData service that has no GET methods implemented?

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 Karkara (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>

 

 

 

 

 

 

 

 

Assigned Tags

      3 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Gaurav Karkara
      Gaurav Karkara

      Thanks Andre for your knowledge sharing.

      Just to add to above info:

      To get X-CSRF-Token using GET, make sure that you are not using entity set in URI because it will give 501 error.

      Execute GET with just 'Technical Service Name' adding X-CSRF-Token = Fetch, and that should give back the token.

      Gaurav

       

      Author's profile photo Andre Fischer
      Andre Fischer
      Blog Post Author

      Good point!

      Author's profile photo Srinivas Rao
      Srinivas Rao

      I remembered reading something similar few weeks back: -

      https://blogs.sap.com/2019/03/28/sap-gw-project-url-and-sample-input-file-generater/

      by @Dharmendra Kumar