Avoiding 5 Common Challenges in Node.js
As part of the NodeSource Support team, I spend much of my time helping our customers analyze and resolve complex issues in Node.js. While factors like architecture and environment mean that some issues are quite unique, there are some familiar struggles that we’ve seen repeatedly from a wide variety of customers. I’ve listed a few of these common and relatively easy-to-avoid challenges below, along with our recommended strategy for avoiding (or resolving) these issues, as I think this information could help more teams working with Node.js avoid major headaches.
Sharing components, modules, or libraries between projects
Issue
The Support team frequently sees questions about the most effective way to share the components, models, and/or libraries between projects. In some cases, our customers are already using Flow and Stampit, which are useful tools for ReactJs components, and they’re looking for tools with less complexity built for Node.js codebases.
Answer
When this question comes up, we usually recommend turning each component (or model, or library) into a module and listing these in each project’s package.json
file. This allows teams to share code across unified codebases by re-using localized modules.
Importing these components to a project can be accomplished with a fairly simple addition to the project’s package.json
file:
“db-models”: “file:../mainproject/models”,
To use this approach, make sure you are using npm@5, or use the linklocal package for earlier npm versions.
Fixing cookie violations in Node.js with Express
Issue
Many teams have web scans to identify and analyze cookie violations in their Node.js environments when Express is also part of their tech stack. Some of the most common cookie violations found are:
- Cookie No
httpOnly
Flag - Cookie Without
secure
Flag: if set to true, “the browser will not send a cookie with the secure flag set over an unencrypted HTTP request”
We’re frequently asked how best to set the HttpOnly
and secure
flags for cookies, and whether that can be done at the server level.
Answer
The default cookie settings in Express aren’t highly secure; however, these settings can be manually tightened to enhance security - for both an application and its users.
httpOnly
- This should be set to “true”-- Flags cookies to be accessible by the issuing web server, which assists in preventing session hijacking.secure
- This should be set to “true”-- which requires TLS/SSL -- to allow the cookie to only be used with HTTPS requests, and not insecure HTTP requests. For more information about how to deal with this issue, I recommend checking out these two blog posts:
- 9 Security Tips to Keep Express from Getting Pwned - NodeSource
- Security Best Practices for Express in Production
Migrate a Java service to Node.js for specific tasks
Issue
We often talk to teams who are working to migrate individual tasks or functionality from Java into a microservices-oriented Node.js application. The best practices approach is to replace a single, monolithic Java app with multiple Node.js apps, each of which is dedicated to a specific task or closely-related set of tasks. We’re frequently asked to recommend a library or pattern that will allow a Node.js app to read from an OracleDB and push to an MQ-enabled application.
Answer
To connect to an OracleDB, we recommend the node-oracledb package, which is developed and maintained by Oracle and includes detailed documentation and examples.
There are a number of ways to access MQ from Node.js, depending on your needs:
-
Take a look at the MQ Light client. MQ supports connections from MQ Light clients via AMQP channels.
-
MQTT.js is a client library for the MQTT protocol. MQ supports connections from MQTT clients via the XR service and Telemetry channels.
-
MQ versions 9.0.4 and higher include a simple REST API for messaging that is accessible from any environment.
When migrating from a Java project or starting a new Node.js project we also recommend:
Don’t use console.log
or console.error
; instead utilize an abstraction library like Winston to control logging levels.
Set the ability to adjust logging level using env variables
Identify the most appropriate package for your needs.
Issue
The npm registry contains more than 800,000 packages, so it’s not surprising that teams have a hard time deciding which package offers both the features and functionality as well as the level of security that is most suitable for their Node.js applications. Among the most common asks we see are recommendations related to creating pdfs, managing RxJS and Promises, and setting up proxy servers and http error handling. That said, needs vary wildly by project, so the advice below is intended to be generally applicable.
Answer
There are a few tools in the Node ecosystem that allow easy checking for vulnerabilities in Node.js application dependencies. These tools are highly valuable in as they can ensure that the packages installed in an application have no known vulnerabilities, and can prevent the installation of package updates if a vulnerability has been detected in a more recent package version.
Once basic security checks have been passed, we recommend looking for the following factors to help you decide which package is best:
- Consistent, ongoing activity in the source code repository
- Acceptable resolution time for issues reported by other users (what is “acceptable” might vary depending on your application and needs)
- The frequency (and recency) of releases which include fixes and new features are released
- Presence of up-to-date documentation of the package code and features, ideally with examples
- Do a general code check to ensure all the features you’ll need are working as expected
Increase the data submission limit in HTTP responses
Issue
For teams using Node.js and Express, we often hear that a POST request containing a large body of JSON is returning a 413: Payload Too Large
response. Most of the time, the engineers we talk to want to know how to safely increase the size limit of the request body.
Answer
There are multiple ways to safely increase the size limit of the request body.
For a quick fix, either of the following two options would work:
app.use(BodyParser.json({ limit: ‘50mb’, type: ‘application/json’ }))
app.use(BodyParser.urlencoded({ limit: ‘50mb’, ‘extended’: ‘true’, parameterLimit: 50000 }));
Both of the above examples raise the maximum size of the request body to 50mb; in the second example, the parameterLimit
value is also defined.
While a quick fix will work, implementing a caching solution with Redis is a good option too. The idea is to store the data in cache and then send a reference from the client to the data instead of sending a big payload.
Similarly, you will not need to receive back a massive amount of data in JSON format; instead, you send the reference from the client and retrieve the cached info at the backend. This allows comparatively lightweight requests and avoids a negative impact on the performance of the application.
Hopefully the suggestions above help your team resolve (or avoid entirely) some of the most common issues reported by our Node.js Support customers. If you have questions or are experiencing an issue not covered above, feel free to contact us on Twitter @NodeSource, or consider joining one of our upcoming Office Hours sessions, which are hosted by one of our senior Solutions Architects and open to anyone with Node.js-related questions.