If you are a JavaScript developer then you have multiple options and frameworks for connecting to and working with SAP HANA databases. It’s easy to be overwhelmed with too many options, some of which even seem to be overlapping in functionality. In this blog post series, I’d like to walk the reader through the assorted options and discuss the strengths and best usages of each.
You might also wonder why I only talk about JavaScript. The HANA Client does contain tooling for a variety of different programming languages and environments. From Java, Python .Net, Go, Ruby; the list is quite large. But JavaScript has a special history here thanks to SAP HANA Extended Application Services or XS. XS and XS Advanced have a history as the application server delivered with SAP HANA on premise installations. JavaScript was the only programming language supported in XS Classic. Even if you are doing SAP HANA Cloud development on SAP BTP today, a great many people choose JavaScript/Node.js as their starting point. We also must consider the wealth of existing development already done in JavaScript that needs to be updated and maintained in modern XSA or Cloud based environments.
Framework For Samples
In each section, there are code samples to support the tool we are discussing. All the code for these samples is available in GitHub here: https://github.com/SAP-samples/sap-tech-bytes/tree/2022-03-17-hana-javascript. The project is a basic Node.js project with no target deployment. It can run against HANA on premises (including HANA Express) or SAP HANA Cloud. The project is designed to run locally in Visual Studio Code, or in SAP Business Application Studio or there is also Devcontainer / Codespace support. It also is using ES Modules and TypeScript JSDoc Annotations to help improve readability and add code completion and stricter syntax checking in most development environments.
Personally, I built the samples using VSCode locally which does require having a Node.js runtime installed on your system as well. But if you are unsure about installing any or all the perquisites, then I recommend one of the hosted options like SAP Business Application Studio or Devcontainers.
In all the samples and different approaches, we are about to look at, the connection to the SAP HANA database is always handled by the @sap/xsenv module. We will talk about that module more in a minute once we get into the samples, but for now it’s enough to know that it supports connecting to HANA regardless of if you are running the code on XSA, Cloud Foundry, Kyma/Kubernetes or even running locally. In the local scenario it uses a file named default-env.json to store all the connection details. Such a file can be created by using the hana-cli connect command.
And finally, the data model for the sample has been kept simple so that we can focus on the coding and differences between each of the approaches. I’ve not used any HDI containers or concepts. Only plain SQL connections with named DB users. All the tables/views/procedures I’m using in the samples come from the common SYS schema. I tested everything in SAP HANA Cloud Free Tier using the default DBADMIN user.
@sap/hana-client vs. hdb
Let’s start our discussion with the @sap/hana-client module. Afterall the subject line for this module is “Official SAP HANA Node.js Driver” and if you look up Node.js Application Programming in the SAP HANA Client Programming Documentation this is the one and only module/library that it talks about. So seemingly straight forward. Well not so fast…
There is also a Node.js module named hdb and the description on it says, “SAP HANA Database Client for Node”. Further reading reveals that both hdb and @sap/hana-client are support by SAP. So, both are “official” HANA client drivers in that regard. But there is some guidance here in the documentation for the hdb module: “When starting a new project, it is encouraged to use the fully featured @sap/hana-client driver”. That’s a clear-cut recommendation for one module over the other. That same documentation for the hdb module even has a nice comparison table (please always refer to the original documentation for the definitive version of this table):
From this recommendation it might seem you can discard hdb as a relic of time past (it was the first version of the HANA Client for Node.js before @sap/hana-client was delivered). But then you might be surprised to see that the SAP Cloud Application Programming Model supports both modules but since July 2021 defaults to hdb not @sap/hana-client. If there is so much more feature support in @sap/hana-client, why does CAP default to hdb?
Architectural Differences
There are some important architectural differences between @sap/hana-client and hdb that are critical for any developer to consider before choosing between the two. This is described right in the prerequisites for @sap/hana-client:
This driver communicates with the native HANA libraries, and thus requires platform-specific native binaries. The official hosted version includes precompiled libraries for Linux, Windows and Mac OS X.
On the other hand, the hdb module is a “pure” JavaScript implementation with no precompiled or native libraries. In fact, if you look at the package.json for hdb module it only has one productive dependency to iconv-lite. You are trading features for a much smaller installation footprint. The hdb module is 101 files and less than half a Mb on disk
By comparison @sap/hana-client is over 120Mb, almost all taken up by the prebuild folder with the OS specific precompiled libraries. And keep in mind that in a single project it’s possible for the same module multiple times (at different versions). You can quickly balloon your entire project to half a Gb or more.
Therefore, you must ask yourself the question: Do I really need one or more of those features that only the @sap/hana-client supports? If so, then certainly start with that module. But if not then consider the size and OS/Native library implications carefully.
This was a decision I also faced a few months ago. I’m the primary maintainer of the hana-cli sample code project. Since the beginning it had used @sap/hana-client (and @sap/hdbext + sap-hdbext-promisfied which we will talk about more in the next part of this blog post series). But the installation size and complexity of the resulting multiple copies of @sap/hana-client this created was starting to cause problems. Particularly when you start thinking about containerizing your services, a proliferation of multiple native libraries and size limitations becomes even more of a concern. Therefore, I made the decision in January, 2022 to rewrite the entire project to use hdb instead.
Coding Differences
Luckily, the architectural differences are far more drastic than the coding differences between these two modules. Let’s look at two examples side by side. One that uses @sap/hana-client and one that uses hdb module to perform a basic SQL statement.
In both approaches we use @sap/xsenv to load a service definition with the label “hana“. This module is responsible for inspecting the environment and pulling and adapting the service details regardless of if the information is coming from a local default-env.json, a Cloud Foundry or XSA service binding or a Kubernetes/Kyma Secret. This makes your code with either HANA client module very portable to different deployment targets. The main difference is that the data structure that is returned from @sap/xsenv matches exactly the format expected by the hdb module’s createClient function.
The @sap/hana-client, on the other hand, expects slightly different metadata formatting. For example, it wants the host and port to be combined into a single field. There are also some naming differences. It doesn’t create a material difference, but it can be annoying if you are used to utilizing the @sap/xsenv module. Luckily, we will see in the next part of this blog post series how the wrapper module, @sap/hdbext, can help avoid this inconsistency between @sap/xsenv and @sap/hana-client.
Beyond the expected connection options formatting and the difference in naming and structure of the create* command (createClient vs. createConnection), the remaining code sample between the two modules is identical.
Closing
While it feels like we’ve covered a lot of ground in this initial blog post, there is still so much more to cover when it comes to HANA client tools for JavaScript. As I’ve hinted in several places there are more wrapper modules that run on top of @sap/hana-client and hdb. There is also more to using HANA Client tools than a simple SQL statement. What happens when you need to call a Stored Procedure for example. Or maybe you don’t like the callback nature of this first example we looked out and want to take advantage of newer JavaScript features like Promises and Async/Await.
Then in the next part we will look at the functionality provided by wrapper modules like @sap/hdbext, sap-hdbext-promisfied, and sap-hdb-promisfied. All the examples have shown JavaScript running standalone from the command line. But more likely you need to use the functionality within a web enabled service of some sort. Also, in Part 3 we will look at how these tools can be used with express.
In the final part we will look at two specialized tooling use cases. After we have the historic XSJS approach that still might be useful today for backwards compatibility with legacy code. And more looking to the future we also have the SAP Cloud Application Programming Model. How should each of these frameworks be considered in your choice of HANA tooling if you are a JavaScript developer?
Part 1: hana-client vs. hdb – This blog post