3 weeks ago - last edited 3 weeks ago
Hello experts,
We have a requirement for a non-SAP cloud system to POST a simple JSON paylod to SAP S/4 and the schema is something similar to
{
"event": "initiated",
"date": "2021-10-12T19:26:01Z",
"data": {
"id": "MMM12345678",
"amount": "100",
"currency": "GBP",
"payment_method": {
"type": "card"
},
"fields": {
"reference": "REF-1234",
"id": "123456789"
},
"payer": {
"first_name": "TEST",
"last_name": "TESTL",
"email": "Test.Test@Test.com"
}
}
}
No GET needed. What is the best way to handle this? REST handler class or an ODATA service using SEGW or ODATA service using RAP. If RAP is the reommended way, how to define the nested json structure as custom entity for the above payload please?
Thank you.
Sathya
Request clarification before answering.
Hello Sathya,
if you have such an RAP Webservice in your SAP, you can call it with POST request. Let say you have orders( root ) and its items( children)
the http post request you can call it something like (curl...) :
curl --location --request POST 'https://<your_sap_system>/sap/opu/odata4/sap/zui_salesorder_srv/0001/$batch?sap-client=050
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: Basic <your_base64_encoded_credentials>' \
--data-raw '{
"SalesOrderId": "1000000002",
"Description": "Sales Order via curl",
"to_Items": [
{
"ItemId": "000001",
"ProductId": "MATERIAL01",
"Quantity": 2.5
},
{
"ItemId": "000002",
"ProductId": "MATERIAL02",
"Quantity": 8.0
}
]
}'
to_items is your assotiation to children / items.....
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hello Sathya,
If you are going to use in your task RAP Object ( Root+Child etc..) as suggested, you can use unmanaged save. see docu: Integrating Unmanaged Save in Managed Business Objects
Here you can use your BAPI in the class and its method
save_modified
here you have all you need. Your JSON data are in the importing parameters, because you have defined your rap object root+ child and you can read data of it within query.
Regards
Jarda
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
deep structure data doesn't mean you have to model the bo in that way(hierarchy).
that deep structure data is just the function call paramter
follow this one to implement action in rap which can take deep structure data as parameter
for the BO, you can just define a dummy custom entity as your root and implement a action by following that blog.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
{{ or nested structure is no problem. The main thing to declare ABAP structure to map it. No matter if you user RAP or if_http_extension~handle_request
lets suppose you use SICF WebAPI with if_http_extension~handle_request
there in the handler class:
You can define nested structures in a TYPE or TYPESblock. Example:
TYPES: BEGIN OF ty_payment_method,
type TYPE string,
END OF ty_payment_method.
TYPES: BEGIN OF ty_fields,
reference TYPE string,
id TYPE string,
END OF ty_fields.
TYPES: BEGIN OF ty_payer,
first_name TYPE string,
last_name TYPE string,
email TYPE string,
END OF ty_payer.
TYPES: BEGIN OF ty_data,
id TYPE string,
amount TYPE string,
currency TYPE string,
payment_method TYPE ty_payment_method,
fields TYPE ty_fields,
payer TYPE ty_payer,
END OF ty_data.
TYPES: BEGIN OF ty_json_root,
event TYPE string,
date TYPE string,
data TYPE ty_data,
END OF ty_json_root.
2. Parse JSON using /ui2/cl_json or cl_trex_json_deserializer
DATA: lv_json_string TYPE string,
ls_json_data TYPE ty_json_root.
" Assuming you already received the JSON payload into lv_json_string
CALL METHOD /ui2/cl_json=>deserialize(
EXPORTING
json = lv_json_string
CHANGING
data = ls_json_data
EXCEPTIONS
others = 1 ).
IF sy-subrc <> 0.
" Handle error
ENDIF.
You now have all the fields parsed into your ABAP structure ls_json_data.
3. Use the data
Now you can use it like any ABAP structure:
WRITE: / 'Event:', ls_json_data-event,
/ 'Date:', ls_json_data-date,
/ 'Payment ID:', ls_json_data-data-id,
/ 'Amount:', ls_json_data-data-amount,
/ 'Currency:', ls_json_data-data-currency,
/ 'Payer:', ls_json_data-data-payer-first_name, ls_json_data-data-payer-last_name,
/ 'Email:', ls_json_data-data-payer-email.
Ensure that you receive the request body using server->request->get_cdata() or get_input_stream() if you're implementing your own ICF handler class (implementing IF_HTTP_EXTENSION).If you're using SAP Gateway or RAP, similar JSON parsing applies with the appropriate context entity.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
root:-
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Event Root'
@ObjectModel.compositionRoot: true
define view entity ZI_Event
as select from zevent
{
key id as EventId,
event,
@ObjectModel.association.type: [#TO_COMPOSITION_CHILD]
_Payer
}
Thanks
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
yes RAP as the preferred option. use @ObjectModel.compositionRoot and @ObjectModel.composition to handle nesting
the root view of the hierarchy must be annotated with @ObjectModel.compositionRoot: true .
Thanks,
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
70 | |
21 | |
9 | |
7 | |
6 | |
6 | |
5 | |
5 | |
4 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.