Call Node.js or Python Functions from ABAP (2023)

Node.js rich ecosystem offers plenty of functions and utilities. Using node-rfc server bindings, these assets can be consumed from ABAP, just like standard ABAP functions. SAP Open Source node-rfc connector and SAP NW RFC SDK Library make it possible.

For more info check the node-rfc server documentation and server examples. Example given here is for Node.js platform and it works the same way with Python, using PyRFC.

Background RFC protocol is currently supported for Python and work in progress for Node.js.

Node.js server source code: server-test-blog.mjs

ABAP client code: zserver_stfc_struct.abap

How it works?

When ABAP report for example calls an ABAP function in Node.js system, over SAP RFC protocol, the node-rfc server will route that call to JavaScript function, registered in node-rfc server to serve requested ABAP function. ABAP function call parameters are automatically transformed to JavaScript and node-rfc server function is invoked. After server function is completed, result is automatically transformed to ABAP format and send back to ABAP client. All standard ABAP RFC call parameters can be used, like ABAP variable (JavaScript variable), ABAP structure (JavaScript “plain” object) or ABAP table (JavaScript array of “plain” objects).

Rather then manually defining ABAP interface the node-rfc server function, the node-rfc can re-use the signature of already existing ABAP function, or empty ABAP function can be created, just to define ABAP function interface for node-rfc server function..

Let try it in real systems, a notebook with Node.js and ABAP system.

ABAP function module signature for Node.js function

Let use the interface of ABAP function STFC_STRUCTURE, to call JavaScript function which we will create. The STFC_STRUCTURE expects one input structure, IMPORTSTRUCT and returns one variable, the RESPTEXT string and one structure, ECHOSTRUCT. There is also a table parameter RFCTABLE:

FUNCTION STFC_STRUCTURE.*"----------------------------------------------------------------------*"*"Lokale Schnittstelle:*" IMPORTING*" VALUE(IMPORTSTRUCT) LIKE RFCTEST STRUCTURE RFCTEST*" EXPORTING*" VALUE(ECHOSTRUCT) LIKE RFCTEST STRUCTURE RFCTEST*" VALUE(RESPTEXT) LIKE SY-LISEL*" TABLES*" RFCTABLE STRUCTURE RFCTEST*"----------------------------------------------------------------------

Here is our Node.js function, to be called from ABAP using these parameters:

function my_stfc_structure(request_context, abap_input) { // inspect request context const attributes = request_context["connection_attributes"]; console.log( "[js] my_stfc_structure context:", attributes["sysId"], attributes["client"], attributes["user"], attributes["progName"]); console.log("[js] my_stfc_structure input:", abap_input.IMPORTSTRUCT); // prepare response for ABAP client const echostruct = abap_input.IMPORTSTRUCT; echostruct.RFCINT1 = 2 * echostruct.RFCINT1; echostruct.RFCINT2 = 3 * echostruct.RFCINT2; echostruct.RFCINT4 = 4 * echostruct.RFCINT4; const abap_output = { ECHOSTRUCT: echostruct, RESPTEXT: `~~~ Node server here ~~~`, }; console.log("[js] my_stfc_structure response:", abap_output); // return response data return abap_output;}

Here is Node.js function call from ABAP client, from ABAP test report:

call function 'STFC_STRUCTURE' destination 'NWRFC_SERVER_OS' exporting importstruct = ls_struct importing echostruct = ls_struct resptext = lv_resp tables rfctable = lt_table exceptions communication_failure = 1 message lv_error_message system_failure = 2 message lv_error_message.

To make this ABAP function call into Node.js work just like standard ABAP function call, following steps shall be done, covered in follow-up sections in detail

  • ABAP system: Configure RFC destination for node-rfc server
  • Node.js system: Configure node-rfc server connections to ABAP system
  • Node.js system: Create Node.js function to be called from ABAP and launch the server
  • ABAP system: Call Node.js function

Configure RFC destination for node-rfc server

Using transaction SM59 create RFC destination of type TCP/IP connection (“T”), like for example

Call Node.js or Python Functions from ABAP (1)

RFC destination configuration – technical settings

If bgRFC protocol shall be supported by node-rfc server, configure the basXML serializer option here:

Call Node.js or Python Functions from ABAP (2)

RFC destinatin configuration – bgRFC support

Configure node-rfc server connections for ABAP system

node-rfc server requires two RFC destinations for ABAP system, configured in sapnwrfc.ini file in Node.js system.

The first destination, “MME”, is RFC client destination, the node-rfc can use to call ABAP functions. This client connection is used by node-rfc server to obtain ABAP STFC_STRUCTURE function definition, so that node-rfc server can automatically transform ABAP STFC_STRUCTURE call data to JavaScript and vice versa.

The second destination, “MME_GATEWAY”, is RFC server destination, open after server is launched and used for listening on ABAP client requests.

sapnwrfc.ini

DEST=MMEUSER=demoPASSWD=welcomeASHOST=system51SYSNR=00CLIENT=620LANG=ENTRACE=0DEST=MME_GATEWAYGWSERV=sapgw00GWHOST=coevi51PROGRAM_ID=RFCSERVERREG_COUNT=1

Start node-rfc server

After SAP NW RFC SDK binaries are downloaded and installed on your Node.js system, you can create empty folder and install node-rfc

mkdir servercd servernpm init -ynpm install node-rfc

Now the first server test can be done, to verify ABAP system connections. Create sapnwrfc.ini file in project root directory and create test script, like:

import {RfcLoggingLevel, Server} from "node-rfc";// Create server instance, initially inactiveconst server = new Server({ serverConnection: { dest: "MME_GATEWAY" }, clientConnection: { dest: "MME" }, // Server options are optional serverOptions: { logLevel: RfcLoggingLevel.error, // authHandler: authHandler, },});(async () => { try { // Start the server await server.start(); console.log( `[js] Server alive: ${server.alive} client handle: ${server.client_connection}`, `server handle: ${server.server_connection}` ); } catch (ex) { // Catch errors, if any console.error(ex); }})();// Close the server after 10 secondslet seconds = 10;const tick = setInterval(() => { console.log("tick", --seconds); if (seconds <= 0) { server.stop(() => { clearInterval(tick); console.log("bye!"); }); }}, 1000);

Now open again the NWRFC_SERVER_OS RFC destination using SM59 transaction and find “Connection Test” button

Call Node.js or Python Functions from ABAP (3)

RFC destination – connection test

Start your test script in Node.js system and after server alive message press the “Connection Test” button. When RFC connection with ABAP system is working, the output looks like this:

Call Node.js or Python Functions from ABAP (4)

RFC destination connection test output

Now when RFC connectivity is working let create Node.js function and call it from ABAP.

Create Node.js function to be called from ABAP and launch the server

Let add “my_stfc_structure” JavaScript server function, to receive ABAP calls of STFC_STRUCTURE function in Node.js system. Two additions are required in our test script, the server function implementation and registration.

Server function requires nothing special for node-rfc server, it shall implement only “plain” logic to calculate the response for ABAP client. Also promise can be returned.

The first parameter is request_context, just in case the function implementation shall consider it. The second parameter is JavaScript object with ABAP parameters, as defined by ABAP STFC_STRUCTURE function signature.

// Server functionfunction my_stfc_structure(request_context, abap_input) { const connection_attributes = request_context["connection_attributes"]; console.log( "[js] my_stfc_structure context:", connection_attributes["sysId"], connection_attributes["client"], connection_attributes["user"], connection_attributes["progName"] ); console.log("[js] my_stfc_structure input:", abap_input.IMPORTSTRUCT); const echostruct = abap_input.IMPORTSTRUCT; echostruct.RFCINT1 = 2 * echostruct.RFCINT1; echostruct.RFCINT2 = 3 * echostruct.RFCINT2; echostruct.RFCINT4 = 4 * echostruct.RFCINT4; const abap_output = { ECHOSTRUCT: echostruct, RESPTEXT: `~~~ Node server here ~~~`, }; console.log("[js] my_stfc_structure response:", abap_output); return abap_output;}

The server function is registered using node-rfc server “addFuncion” method, telling the server to route ABAP STFC_STRUCTURE function calls to JavaScript function “my_stfc_structure”:

 server.addFunction("STFC_STRUCTURE", my_stfc_structure);

ABAP data transformations to/from JavaScript are done by node-rfc server automatically.

Our test script is now ready and the node-rfc server can be started, to serve ABAP client calls:

import { RfcLoggingLevel, Server } from "node-rfc";// Create server instance, initially inactiveconst server = new Server({ serverConnection: { dest: "MME_GATEWAY" }, clientConnection: { dest: "MME" }, // Server options are optional serverOptions: { logLevel: RfcLoggingLevel.error, // authHandler: authHandler, },});// Server functionfunction my_stfc_structure(request_context, abap_input) { const connection_attributes = request_context["connection_attributes"]; console.log( "[js] my_stfc_structure context:", connection_attributes["sysId"], connection_attributes["client"], connection_attributes["user"], connection_attributes["progName"] ); console.log("[js] my_stfc_structure input:", abap_input.IMPORTSTRUCT); const echostruct = abap_input.IMPORTSTRUCT; echostruct.RFCINT1 = 2 * echostruct.RFCINT1; echostruct.RFCINT2 = 3 * echostruct.RFCINT2; echostruct.RFCINT4 = 4 * echostruct.RFCINT4; const abap_output = { ECHOSTRUCT: echostruct, RESPTEXT: `~~~ Node server here ~~~`, }; console.log("[js] my_stfc_structure response:", abap_output); return abap_output;}(async () => { try { // Register server function server.addFunction("STFC_STRUCTURE", my_stfc_structure); console.log( `[js] Node.js function '${my_stfc_structure.name}'`, "registered as ABAP 'STFC_STRUCTURE' function" ); // Start the server await server.start(); console.log( `[js] Server alive: ${server.alive} client handle: ${server.client_connection}`, `server handle: ${server.server_connection}` ); } catch (ex) { // Catch errors, if any console.error(ex); }})();// Close the server after 10 secondslet seconds = 10;const tick = setInterval(() => { console.log("tick", --seconds); if (seconds <= 0) { server.stop(() => { clearInterval(tick); console.log("bye!"); }); }}, 1000);

When test script is started in Node.js system and ABAP test report calls STFC_STRUCTURE function in Node.js system, the test script output looks like:

ts-node ci/test/server-test.ts (py3.11.4) ✘ 1 main ◼[js] Node.js function 'my_stfc_structure' registered as ABAP 'STFC_STRUCTURE' function[js] Server alive: false client handle: 5554800128 server handle: 0tick 9tick 8[js] my_stfc_structure context: MME 620 D037732 ZSERVER_STFC_STRUCT[js] my_stfc_structure input: { RFCFLOAT: 0, RFCCHAR1: '', RFCINT2: 2, RFCINT1: 1, RFCCHAR4: '', RFCINT4: 4, RFCHEX3: <Buffer 00 00 00>, RFCCHAR2: '', RFCTIME: '000000', RFCDATE: '00000000', RFCDATA1: '', RFCDATA2: ''}[js] my_stfc_structure response: { ECHOSTRUCT: { RFCFLOAT: 0, RFCCHAR1: '', RFCINT2: 6, RFCINT1: 2, RFCCHAR4: '', RFCINT4: 16, RFCHEX3: <Buffer 00 00 00>, RFCCHAR2: '', RFCTIME: '000000', RFCDATE: '00000000', RFCDATA1: '', RFCDATA2: '' }, RESPTEXT: '~~~ Node server here ~~~'}tick 7tick 6tick 5^C

Calling Node.js function from ABAP

Here is ABAP test report for calling Node.js function, used in this example

*&---------------------------------------------------------------------**& Report ZSERVER_STFC_STRUCT*&---------------------------------------------------------------------**&*&---------------------------------------------------------------------*report zserver_stfc_struct.data lv_echo like sy-lisel.data lv_resp like sy-lisel.data ls_struct like rfctest.data lt_table like table of rfctest.data lv_error_message type char512.ls_struct-rfcint1 = 1.ls_struct-rfcint2 = 2.ls_struct-rfcint4 = 4.insert ls_struct into table lt_table.call function 'STFC_STRUCTURE' destination 'NWRFC_SERVER_OS' exporting importstruct = ls_struct importing echostruct = ls_struct resptext = lv_resp tables rfctable = lt_table exceptions communication_failure = 1 message lv_error_message system_failure = 2 message lv_error_message.if sy-subrc eq 0. write: / 'rfcint1:', ls_struct-rfcint1. write: / 'rfcint2:', ls_struct-rfcint2. write: / 'rfcint4:', ls_struct-rfcint4. write: / 'resptext:', lv_resp.else. write: 'subrc :', sy-subrc. write: / 'msgid :', sy-msgid, sy-msgty, sy-msgno. write: / 'msgv1-4:', sy-msgv1, sy-msgv2, sy-msgv3, sy-msgv4. write: / 'message:', lv_error_message. exit.endif.

When node-rfc server is running and this ABAP report started, the output looks like:

Call Node.js or Python Functions from ABAP (5)

Node.js server call output

Error Handling

In case of error, the server function shall raise exception message and error message will be returned to ABAP, with RFC_EXTERNAL_FAILURE error code.

 throw new Error("my_stfc_function error"); console.log("[js] my_stfc_structure response:", abap_output); return abap_output;}

ABAP report output

Call Node.js or Python Functions from ABAP (6)

ABAP test report – error

Logging

When activated, the log is saved in local file: _noderfc.log and above mentioned error looks like:

Call Node.js or Python Functions from ABAP (7)

Error log

Enjoy calling Node.js function from ABAP 🙂

FAQs

Should I use NodeJS or Python? ›

Node. js is recommended for building fast, real-time applications, while Python is a popular language for machine learning and data analytics. That said, both languages have lots of use cases.

Why choose NodeJS over Python? ›

js vs Python, Node. js is faster due to JavaScript, whereas Python is very slow compared to compiled languages. Node. js is suitable for cross-platform applications, whereas Python is majorly used for web and desktop applications.

Why not to use NodeJS? ›

Disadvantages of Node.js

js and JavaScript, the biggest concern is the fact that your code is completely dependent on the NPM package manager. This means that if there is a problem within one of your dependencies, it can cause problems for your entire application.

What is the difference between Python API and Node API? ›

Node is better for web applications and website development, whereas Python is best suitable for back-end applications, numerical computations, and machine learning. Nodejs utilize JavaScript interpreters, whereas Python uses CPython as an interpreter.

Which is faster Python or NodeJS? ›

Which is faster, NodeJS or Python? Node. js is faster than Python because it uses the V8 engine to interpret the codes. It has single module caching and has an event-driven architecture, whereas Python uses single-flow, which means it executes statements one by one as they appear on the screen.

Will Python replace NodeJS? ›

No, because Node. js works with JavaScript, and Python has CPython.

Is it worth to learn NodeJS in 2023? ›

So, without a doubt, Node. js is immensely popular. It is basically JavaScript, and as you may know, JavaScript is not only the most popular programming language but also, it is a core technology of the World Wide Web. So, it is definitely worth learning an incredibly popular language.

What is NodeJS best suited for? ›

Node js is used for building single-page applications and dynamic websites due to its ability to handle multiple requests asynchronously. It can serve dynamic content to users, improving the overall user experience.

What are the disadvantages of NodeJS? ›

Drawbacks of Node. js
  • Its performance is reduced with heavy computational tasks. Node. ...
  • It lacks library support. You already know from the upper section that Node. ...
  • It has tons of nested callbacks. Node. ...
  • It has an unstable API. Node. ...
  • It has high demand but few experienced developers.

Why is NodeJS so difficult? ›

js is an advanced programming skill, the more computer science experience and training you have, the easier it will be to learn. The biggest hurdle for Node. js students is already surmounted because it is learning HTML/CSS and JavaScript, which is required to start learning Node. js.

Is there something better than NodeJS? ›

Python for SMEs

Python as a nodejs alternative is undoubtedly more secure than some other well-known languages. Thanks to frameworks such as Django, which have built-in security features that protect the application from the many security threats lurking on the Internet.

What is the most used API in Python? ›

Here's a list of top Python REST API Frameworks:
  • Django REST.
  • Flask RESTful.
  • FastAPI.
  • Pyramid.
  • Falcon.
  • Bottle.
  • Eve.
  • Sanic.
May 16, 2023

What is the best language for API calls? ›

From our experience in developing enterprise APIs, we have found that Python, Flask, Node, JS, and Express are the best languages ​​for building EFFICIENT web application APIs.

What are the 4 major types in API? ›

There are four different types of APIs commonly used in web services: public, partner, private and composite. In this context, the API "type" indicates the intended scope of use.

Should I learn NodeJS after Python? ›

Node. js is a better choice if your focus is on web applications and web site development. Python is better if you want to do multiple things - web applications, integration with back end applications, such as, numerical computations, machine learning, network programming.

Is Python good for backend? ›

Python is one of the most popular and widely used languages for backend programming, but it may not necessarily be the "best" language for every situation. The choice of language depends on the specific needs and requirements of your project.

Is Python more secure than NodeJS? ›

js is more secure than Python as it supports code sandboxing and a sandbox-like environment. On the other hand, Python offers more robust security libraries and tools that help ensure fast development. Node. js is more cost-effective than Python due to its simplicity and fast development time.

Top Articles
Latest Posts
Article information

Author: Kerri Lueilwitz

Last Updated: 11/21/2023

Views: 6050

Rating: 4.7 / 5 (67 voted)

Reviews: 82% of readers found this page helpful

Author information

Name: Kerri Lueilwitz

Birthday: 1992-10-31

Address: Suite 878 3699 Chantelle Roads, Colebury, NC 68599

Phone: +6111989609516

Job: Chief Farming Manager

Hobby: Mycology, Stone skipping, Dowsing, Whittling, Taxidermy, Sand art, Roller skating

Introduction: My name is Kerri Lueilwitz, I am a courageous, gentle, quaint, thankful, outstanding, brave, vast person who loves writing and wants to share my knowledge and understanding with you.