{"id":46975,"date":"2022-06-04T00:00:00","date_gmt":"2022-06-04T00:00:00","guid":{"rendered":"urn:uuid:df52d1c7-afb1-aa56-cc56-f84057029d11"},"modified":"2022-06-04T00:00:00","modified_gmt":"2022-06-04T00:00:00","slug":"tutorial-how-to-build-your-first-node-js-grpc-api","status":"publish","type":"post","link":"https:\/\/www.threatshub.org\/blog\/tutorial-how-to-build-your-first-node-js-grpc-api\/","title":{"rendered":"Tutorial: How to Build Your First Node.js gRPC API"},"content":{"rendered":"<p><img decoding=\"async\" src=\"https:\/\/www.trendmicro.com\/content\/dam\/trendmicro\/global\/en\/devops\/22\/f\/grpc-api-tutorial\/build-first-node-tn.jpg\"><\/p>\n<p><span class=\"body-subhead-title\">What is gRPC?<\/span><\/p>\n<p>Google Remote Procedure Call (gRPC) is a remote procedure call framework that eases the communication process between client and server applications. It\u2019s high-performing, robust, and lightweight.<\/p>\n<p>These three qualities are due to its data exchange format and the interface definition language used by protocol buffers (protobufs). Protobufs are small and fast due to their data serialization format, which enables smaller packets. This makes them highly suitable for fast data flow and economical storage.<\/p>\n<p>Before building the application program interface (API), it&#8217;s important to understand the features that give gRPC an upper hand over other API technologies like REST and GraphQL.<\/p>\n<p><span class=\"body-subhead-title\">What are the features of gRPC?<\/span><\/p>\n<p>The distinguishing features of gRPC are:<\/p>\n<ul>\n<li><span class=\"rte-red-bullet\">The use of protobufs. Developers must follow a specific format in defining the protobufs. This enforcement plays a significant role in clean code and error reduction.<\/span><\/li>\n<li><span class=\"rte-red-bullet\">The presence of a compiler (protoc) to perform data serialization and deserialization. The protoc does this using automatic code generation that handles the functionality. This relieves developers from the overhead of parsing JSON or XML.<\/span><\/li>\n<li><span class=\"rte-red-bullet\">The reduction of errors and increased efficiency because the protoc compiler parses the data. Developers only focus on other parts of the logic.<\/span><\/li>\n<li><span class=\"rte-red-bullet\">gRPC uses HTTP\/2, which is faster than HTTP\/1 used by other technologies. Specifically, gRPC supports bidirectional streaming, enabling the multiplexed forms of communication between systems.<\/span><\/li>\n<\/ul>\n<p>This article will demonstrate how to develop a basic Node.js gRPC API that salts and hashes a password received from a client endpoint. Also, it will give an overview of some of the potential security pitfalls of gRPC and the best practices for avoiding them.<\/p>\n<p><span class=\"body-subhead-title\">Prerequisites<br \/><\/span><br \/>To best follow this walkthrough, the following prerequisites are required:<\/p>\n<ul>\n<li><span class=\"rte-red-bullet\">A basic understanding of Node.js and the ability to create a basic app<\/span><\/li>\n<li><span class=\"rte-red-bullet\">Node.js installed on your machine<\/span><\/li>\n<\/ul>\n<p>While not mandatory, JavaScript knowledge is also quite helpful.<\/p>\n<p><span class=\"body-subhead-title\">Creating the API<br \/><\/span>In the working directory, create a folder named node-grpc. Open the folder and your favorite terminal. Then start the node by running the command below:<\/p>\n<p><span class=\"pre\">npm init -y<\/span><\/p>\n<p>Next, install the required libraries. Both grpc-js and protoc are two open-source libraries that enable you to use gRPC in Node.js. Install them by running these commands:<\/p>\n<p><span class=\"pre\">npm i @grpc\/grpc-js<br \/>npm i @grpc\/proto-loader<\/span><\/p>\n<p>Next, create three files: one for the protobuf definition, one for the client stub, and one for the server code. You can do this using the following command:<\/p>\n<p><span class=\"pre\">touch server.js client-stub.js password.proto<\/span><\/p>\n<p>As the names suggest, server.js contains the server code, client-stub.js, the client code, and the protobuf definition are in the password.proto file.<\/p>\n<p><b>Writing the protobuf definition<\/b><\/p>\n<p>In the password.proto file, paste the following code:<\/p>\n<p><span class=\"pre\">syntax = &#8220;proto3&#8221;;<br \/>message PasswordDetails {<br \/>&nbsp; &nbsp; string id = 1;<br \/>&nbsp; &nbsp; string password = 2;<br \/>&nbsp; &nbsp; string hashValue = 3;<br \/>&nbsp; &nbsp; string saltValue = 4;<br \/>}<br \/>service PasswordService {<br \/>&nbsp; &nbsp; rpc RetrievePasswords (Empty) returns (PasswordList) {}<br \/>&nbsp; &nbsp; rpc AddNewDetails (PasswordDetails) returns (PasswordDetails) {}<br \/>&nbsp; &nbsp; rpc UpdatePasswordDetails (PasswordDetails) returns (PasswordDetails) {}<br \/>}<br \/>message Empty {}<br \/>message PasswordList {<br \/>&nbsp; &nbsp;repeated PasswordDetails passwords = 1;<br \/>}<\/span><\/p>\n<p>The code starts by specifying the syntax version of the protocol buffers. Then, it creates a message definition for a password\u2019s details. You must send all commands to a gRPC API contained in a service. So, in this case, PasswordService contains the commands needed for this tutorial.&nbsp;<\/p>\n<p>The commands taking in and returning message replies are for adding a new password, editing, and reading passwords. The messages passed or replied to and from the endpoints can be empty (Empty) or contain some message. The rest of the message definitions added are for representing empty messages and a list of passwords.<\/p>\n<p><b>The server code<\/b><\/p>\n<p>Start by importing the required modules and your proto file:<\/p>\n<p><span class=\"pre\">const grpc = require(&#8220;@grpc\/grpc-js&#8221;);<br \/>const protoLoader = require(&#8220;@grpc\/proto-loader&#8221;);<br \/>const PROTO_PATH = &#8220;.\/password.proto&#8221;;<\/span><\/p>\n<p>Then, initialize an object for storing the protobuf loader (protoLoader) options in this manner:<\/p>\n<p><span class=\"pre\">const loaderOptions = {<br \/>&nbsp; &nbsp; keepCase: true,<br \/>&nbsp; &nbsp; longs: String,<br \/>&nbsp; &nbsp; enums: String,<br \/>&nbsp; &nbsp; defaults: true,<br \/>&nbsp; &nbsp; oneofs: true,<br \/>};<\/span><\/p>\n<p>The above fields do the following:<\/p>\n<ul>\n<li><span class=\"rte-red-bullet\">keepCase instructs the protoLoader to maintain protobuf field names.&nbsp;<\/span><\/li>\n<li><span class=\"rte-red-bullet\">longs and enums store the data types that represent long and enum values.&nbsp;<\/span><\/li>\n<li><span class=\"rte-red-bullet\">defaults, when set to true, sets default values for output objects.&nbsp;<\/span><\/li>\n<li><span class=\"rte-red-bullet\">oneof sets virtual <a href=\"https:\/\/developers.google.com\/protocol-buffers\/docs\/proto3?hl=en#oneof\" target=\"_blank\" rel=\"noopener\">oneof<\/a> properties to field names.&nbsp;<\/span><\/li>\n<\/ul>\n<p>You can find more information about setting the options object <a href=\"https:\/\/github.com\/grpc\/grpc-node\/tree\/master\/packages\/proto-loader#readme\" target=\"_blank\" rel=\"noopener\">here<\/a>.<\/p>\n<p>Next, initialize the package definition object by passing the protobuf file and the options object in the protobuf loader\u2019s loadSync method:<\/p>\n<p><span class=\"pre\">\/\/ initializing the package definition<br \/>var packageDef = protoLoader.loadSync(PROTO_PATH, loaderOptions);<\/span><\/p>\n<p>To create a gRPC object, call the grpc-js method, loadPackageDefinition while passing in the previously created package definition. Use the object to invoke the gRPC service and, eventually, the commands.<\/p>\n<p><span class=\"pre\">const grpcObj = grpc.loadPackageDefinition(packageDef);<\/span><\/p>\n<p>But before that, you must invoke your Node.js server to add the gRPC services to it. Do that using this line:<\/p>\n<p><span class=\"pre\">const ourServer = new grpc.Server();<\/span><\/p>\n<p>The first two default passwords are in a JavaScript object. Here, you can use your own logic and retrieve data from your storage engine. It can be a database, a serverless platform\u2019s data retrieval logic, a file, and so on.<\/p>\n<p><span class=\"pre\">let dummyRecords = {<br \/>&nbsp; &nbsp; &#8220;passwords&#8221;: [<br \/>&nbsp; &nbsp; &nbsp; &nbsp; { id: &#8220;153642&#8221;, password: &#8220;default1&#8221;, hashValue: &#8220;default&#8221;, saltValue:&nbsp; &nbsp; &nbsp; &nbsp;&#8220;default&#8221; },<br \/>&nbsp; &nbsp; &nbsp; &nbsp; { id: &#8220;234654&#8221;, password: &#8220;default2&#8221;, hashValue: &#8220;default&#8221;, saltValue: &#8220;default&#8221; }]<br \/>};<\/span><\/p>\n<p>Add the service and the commands using the code below:<\/p>\n<p><span class=\"pre\">ourServer.addService(grpcObj.PasswordService.service, {<br \/>&nbsp; &nbsp; \/*our protobuf message(passwordMessage) for the RetrievePasswords was Empty. *\/<br \/>&nbsp; &nbsp; retrievePasswords: (passwordMessage, callback) =&gt; {<br \/>&nbsp; &nbsp; &nbsp; &nbsp; callback(null, dummyRecords);<br \/>&nbsp; &nbsp; },<br \/>&nbsp; &nbsp; addNewDetails: (passwordMessage, callback) =&gt; {<br \/>&nbsp; &nbsp; &nbsp; &nbsp; const passwordDetails = { &#8230;passwordMessage.request };<br \/>&nbsp; &nbsp; &nbsp; &nbsp; dummyRecords.passwords.push(passwordDetails);<br \/>&nbsp; &nbsp; &nbsp; &nbsp; callback(null, passwordDetails);<br \/>&nbsp; &nbsp; },<br \/>&nbsp; &nbsp; updatePasswordDetails: (passwordMessage, callback) =&gt; {<br \/>&nbsp; &nbsp; &nbsp; &nbsp; const detailsID = passwordMessage.request.id;<br \/>&nbsp; &nbsp; &nbsp; &nbsp; const targetDetails = dummyRecords.passwords.find(({ id }) =&gt; detailsID == id);<br \/>&nbsp; &nbsp; &nbsp; &nbsp; targetDetails.password = passwordMessage.request.password;<br \/>&nbsp; &nbsp; &nbsp; &nbsp; targetDetails.hashValue = passwordMessage.request.hashValue;<br \/>&nbsp; &nbsp; &nbsp; &nbsp; targetDetails.saltValue = passwordMessage.request.saltValue;<br \/>&nbsp; &nbsp; &nbsp; &nbsp; callback(null, targetDetails);<br \/>&nbsp; &nbsp; },<br \/>});<\/span><\/p>\n<p>The addService method takes in two parameters: the service, and the commands. Each of the commands takes in a message argument (as defined in the proto file) and a callback function argument. The callback function passes the replies from the commands to the client.<\/p>\n<p>The retrievePasswords method returns all passwords stored in the object. The addNewDetails method inserts new password details to the inner array of your object using the Array.prototype.push method from the message request.&nbsp;<\/p>\n<p>To update a password\u2019s details, the ID of the password comes from the request. The Array.prototype.find method retrieves the details to update using the request details passed in the command, updates the retrieved details, and returns the updated details to the client.<\/p>\n<p>Finally, bind the server to a port and start it using the bindAsync method.<\/p>\n<p><span class=\"pre\">ourServer.bindAsync(<br \/>&nbsp; &nbsp; &#8220;127.0.0.1:50051&#8221;,<br \/>&nbsp; &nbsp; grpc.ServerCredentials.createInsecure(),<br \/>&nbsp; &nbsp; (error, port) =&gt; {<br \/>&nbsp; &nbsp; &nbsp; &nbsp; console.log(&#8220;Server running at http:\/\/127.0.0.1:50051&#8221;);<br \/>&nbsp; &nbsp; &nbsp; &nbsp; ourServer.start();<br \/>&nbsp; &nbsp; }<br \/>);<\/span><\/p>\n<p><b>The client code<\/b><\/p>\n<p>Now you\u2019re ready to salt and hash your passwords. To help achieve this, you need a library called bcrypt. Install it using this command:<\/p>\n<p><span class=\"pre\">npm i bcrypt<\/span><\/p>\n<p>Just like the server code, start by importing the required modules. You create the package definitions and the gRPC object in the same way.<\/p>\n<p><span class=\"pre\">const grpc = require(&#8220;@grpc\/grpc-js&#8221;);<br \/>var protoLoader = require(&#8220;@grpc\/proto-loader&#8221;);<br \/>const PROTO_PATH = &#8220;.\/password.proto&#8221;;<br \/>const bcrypt = require(&#8216;bcrypt&#8217;);<br \/>const options = {<br \/>&nbsp; &nbsp; keepCase: true,<br \/>&nbsp; &nbsp; longs: String,<br \/>&nbsp; &nbsp; enums: String,<br \/>&nbsp; &nbsp; defaults: true,<br \/>&nbsp; &nbsp; oneofs: true,<br \/>};<br \/>var grpcObj = protoLoader.loadSync(PROTO_PATH, options);<br \/>const PasswordService = grpc.loadPackageDefinition(grpcObj).PasswordService;<\/span><\/p>\n<p>You create the client stub by passing the server address and the server connection credentials to the service name constructor.<\/p>\n<p><span class=\"pre\">const clientStub = new PasswordService(<br \/>&nbsp; &nbsp; &#8220;localhost:50051&#8221;,<br \/>&nbsp; &nbsp; grpc.credentials.createInsecure()<br \/>);<\/span><\/p>\n<p>Invoke the commands by passing in the messages as the first parameter and the callback function as parameters. The retrievePasswords service command illustrates this.<\/p>\n<p><span class=\"pre\">clientStub.retrievePasswords({}, (error, passwords) =&gt; {<br \/>&nbsp; &nbsp; \/\/implement your error logic here<br \/>&nbsp; &nbsp; console.log(passwords);<br \/>});<\/span><\/p>\n<p>You generate a salt using the bcrypt.genSalt method by passing in the salt rounds you need. You generate a hash using the bcrypt.hash method by passing in the password and the salt values. In each method, there is a callback function containing any encountered error message, if found, and the result. Set the hash and salt values inside the method bodies as shown.<\/p>\n<p><span class=\"pre\">const saltRounds = 10;<br \/>let passwordToken = &#8220;5TgU76W&amp;eRee!&#8221;;<br \/>let updatePasswordToken = &#8220;H7hG%$Yh33&#8221;<br \/>bcrypt.genSalt(saltRounds, function (error, salt) {<br \/>&nbsp; &nbsp; bcrypt.hash(passwordToken, salt, function (error, hash) {<br \/>&nbsp; &nbsp; &nbsp; &nbsp; clientStub.addNewDetails(<br \/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {<br \/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; id: Date.now(),<br \/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; password: passwordToken,<br \/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hashValue: hash,<br \/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; saltValue: salt,<br \/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; },<br \/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (error, passwordDetails) =&gt; {<br \/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \/\/implement your error logic here<br \/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(passwordDetails);<br \/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br \/>&nbsp; &nbsp; &nbsp; &nbsp; );<br \/>&nbsp; &nbsp; });<br \/>});<br \/>bcrypt.genSalt(saltRounds, function (error, salt) {<br \/>&nbsp; &nbsp; \/\/implement your error logic here<br \/>&nbsp; &nbsp; bcrypt.hash(updatePasswordToken, salt, function (error, hash) {<br \/>&nbsp; &nbsp; &nbsp; &nbsp; \/\/implement your error logic here<br \/>&nbsp; &nbsp; &nbsp; &nbsp; clientStub.updatePasswordDetails(<br \/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {<br \/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \/*<br \/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; This is one of the defaultIDs of our dummy object&#8217;s values.<br \/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; You can change it to suit your needs<br \/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; *\/<br \/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; id: 153642,<br \/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; password: updatePasswordToken,<br \/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hashValue: hash,<br \/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; saltValue: salt,<br \/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; },<br \/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (error, passwordDetails) =&gt; {<br \/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \/\/implement your error logic here<br \/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(passwordDetails);<br \/>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br \/>&nbsp; &nbsp; &nbsp; &nbsp; );<br \/>&nbsp; &nbsp; });<br \/>});<\/span><\/p>\n<p>You should do the hashing and salting on the server. Here, you did the processes in the client just for demonstration purposes. You can learn more about salting and hashing <a href=\"https:\/\/www.thesslstore.com\/blog\/difference-encryption-hashing-salting\/#:~:text=Hashing%20is%20a%20one%2Dway,changes%20the%20hash%20value%20produced.\" target=\"_blank\" rel=\"noopener\">here<\/a>.<\/p>\n<p>Then, run the application by starting the server using the command below:<\/p>\n<p><span class=\"pre\">node server.js<\/span><\/p>\n<p>Add the client stub using node client-stub.js. Uncomment the ones you don\u2019t want to fire at a specific time.<\/p>\n<p>Below are screenshots produced when you run the commands.<\/p>\n<p>retrievePasswords command:<\/p>\n<p> Read More <a href=\"https:\/\/www.trendmicro.com\/en_us\/devops\/22\/f\/grpc-api-tutorial.html\">HERE<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Compared to other API technologies like REST and GraphQL, gRPC is lightweight and exceptionally robust, thanks in large part to its use of protobufs. Interested in exploring how to build your own API? Read on to see how easy it is to do so with Node.js and gRPC. Read More HERE&#8230;<\/p>\n","protected":false},"author":2,"featured_media":46976,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"colormag_page_layout":"default_layout","footnotes":""},"categories":[61],"tags":[9503,9501,9506,9507,9608],"class_list":["post-46975","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-trendmicro","tag-trend-micro-devops-article","tag-trend-micro-devops-cloud-native","tag-trend-micro-devops-expert-perspective","tag-trend-micro-devops-multi-cloud","tag-trend-micro-devops-serverless-security"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Tutorial: How to Build Your First Node.js gRPC API 2026 | ThreatsHub Cybersecurity News<\/title>\n<meta name=\"description\" content=\"ThreatsHub Cybersecurity News | ThreatsHub.org | Cloud Security &amp; Cyber Threats Analysis Hub. 100% Free OSINT Threat Intelligent and Cybersecurity News.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.threatshub.org\/blog\/tutorial-how-to-build-your-first-node-js-grpc-api\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Tutorial: How to Build Your First Node.js gRPC API 2026 | ThreatsHub Cybersecurity News\" \/>\n<meta property=\"og:description\" content=\"ThreatsHub Cybersecurity News | ThreatsHub.org | Cloud Security &amp; Cyber Threats Analysis Hub. 100% Free OSINT Threat Intelligent and Cybersecurity News.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.threatshub.org\/blog\/tutorial-how-to-build-your-first-node-js-grpc-api\/\" \/>\n<meta property=\"og:site_name\" content=\"ThreatsHub Cybersecurity News\" \/>\n<meta property=\"article:published_time\" content=\"2022-06-04T00:00:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.threatshub.org\/blog\/coredata\/uploads\/2022\/06\/tutorial-how-to-build-your-first-node-js-grpc-api.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"641\" \/>\n\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"TH Author\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@threatshub\" \/>\n<meta name=\"twitter:site\" content=\"@threatshub\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"TH Author\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/tutorial-how-to-build-your-first-node-js-grpc-api\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/tutorial-how-to-build-your-first-node-js-grpc-api\\\/\"},\"author\":{\"name\":\"TH Author\",\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/#\\\/schema\\\/person\\\/12e0a8671ff89a863584f193e7062476\"},\"headline\":\"Tutorial: How to Build Your First Node.js gRPC API\",\"datePublished\":\"2022-06-04T00:00:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/tutorial-how-to-build-your-first-node-js-grpc-api\\\/\"},\"wordCount\":1858,\"publisher\":{\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/tutorial-how-to-build-your-first-node-js-grpc-api\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/tutorial-how-to-build-your-first-node-js-grpc-api.jpg\",\"keywords\":[\"Trend Micro DevOps : Article\",\"Trend Micro DevOps : Cloud Native\",\"Trend Micro DevOps : Expert Perspective\",\"Trend Micro DevOps : Multi Cloud\",\"Trend Micro DevOps : Serverless Security\"],\"articleSection\":[\"TrendMicro\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/tutorial-how-to-build-your-first-node-js-grpc-api\\\/\",\"url\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/tutorial-how-to-build-your-first-node-js-grpc-api\\\/\",\"name\":\"Tutorial: How to Build Your First Node.js gRPC API 2026 | ThreatsHub Cybersecurity News\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/tutorial-how-to-build-your-first-node-js-grpc-api\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/tutorial-how-to-build-your-first-node-js-grpc-api\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/tutorial-how-to-build-your-first-node-js-grpc-api.jpg\",\"datePublished\":\"2022-06-04T00:00:00+00:00\",\"description\":\"ThreatsHub Cybersecurity News | ThreatsHub.org | Cloud Security & Cyber Threats Analysis Hub. 100% Free OSINT Threat Intelligent and Cybersecurity News.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/tutorial-how-to-build-your-first-node-js-grpc-api\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/tutorial-how-to-build-your-first-node-js-grpc-api\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/tutorial-how-to-build-your-first-node-js-grpc-api\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/tutorial-how-to-build-your-first-node-js-grpc-api.jpg\",\"contentUrl\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/tutorial-how-to-build-your-first-node-js-grpc-api.jpg\",\"width\":641,\"height\":350},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/tutorial-how-to-build-your-first-node-js-grpc-api\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Trend Micro DevOps : Article\",\"item\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/tag\\\/trend-micro-devops-article\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Tutorial: How to Build Your First Node.js gRPC API\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/\",\"name\":\"ThreatsHub Cybersecurity News\",\"description\":\"%%focuskw%% Threat Intel \u2013 Threat Intel Services \u2013 CyberIntelligence \u2013 Cyber Threat Intelligence - Threat Intelligence Feeds - Threat Intelligence Reports - CyberSecurity Report \u2013 Cyber Security PDF \u2013 Cybersecurity Trends - Cloud Sandbox \u2013- Threat IntelligencePortal \u2013 Incident Response \u2013 Threat Hunting \u2013 IOC - Yara - Security Operations Center \u2013 SecurityOperation Center \u2013 Security SOC \u2013 SOC Services - Advanced Threat - Threat Detection - TargetedAttack \u2013 APT \u2013 Anti-APT \u2013 Advanced Protection \u2013 Cyber Security Services \u2013 Cybersecurity Services -Threat Intelligence Platform\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/#organization\"},\"alternateName\":\"Threatshub.org\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/#organization\",\"name\":\"ThreatsHub.org\",\"alternateName\":\"Threatshub.org\",\"url\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/wp-content\\\/uploads\\\/2025\\\/05\\\/Threatshub_Favicon1.jpg\",\"contentUrl\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/wp-content\\\/uploads\\\/2025\\\/05\\\/Threatshub_Favicon1.jpg\",\"width\":432,\"height\":435,\"caption\":\"ThreatsHub.org\"},\"image\":{\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/x.com\\\/threatshub\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.threatshub.org\\\/blog\\\/#\\\/schema\\\/person\\\/12e0a8671ff89a863584f193e7062476\",\"name\":\"TH Author\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/066276f086d5155df79c850206a779ad368418a844da0182ce43f9cd5b506c3d?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/066276f086d5155df79c850206a779ad368418a844da0182ce43f9cd5b506c3d?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/066276f086d5155df79c850206a779ad368418a844da0182ce43f9cd5b506c3d?s=96&d=mm&r=g\",\"caption\":\"TH Author\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Tutorial: How to Build Your First Node.js gRPC API 2026 | ThreatsHub Cybersecurity News","description":"ThreatsHub Cybersecurity News | ThreatsHub.org | Cloud Security & Cyber Threats Analysis Hub. 100% Free OSINT Threat Intelligent and Cybersecurity News.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.threatshub.org\/blog\/tutorial-how-to-build-your-first-node-js-grpc-api\/","og_locale":"en_US","og_type":"article","og_title":"Tutorial: How to Build Your First Node.js gRPC API 2026 | ThreatsHub Cybersecurity News","og_description":"ThreatsHub Cybersecurity News | ThreatsHub.org | Cloud Security & Cyber Threats Analysis Hub. 100% Free OSINT Threat Intelligent and Cybersecurity News.","og_url":"https:\/\/www.threatshub.org\/blog\/tutorial-how-to-build-your-first-node-js-grpc-api\/","og_site_name":"ThreatsHub Cybersecurity News","article_published_time":"2022-06-04T00:00:00+00:00","og_image":[{"width":641,"height":350,"url":"https:\/\/www.threatshub.org\/blog\/coredata\/uploads\/2022\/06\/tutorial-how-to-build-your-first-node-js-grpc-api.jpg","type":"image\/jpeg"}],"author":"TH Author","twitter_card":"summary_large_image","twitter_creator":"@threatshub","twitter_site":"@threatshub","twitter_misc":{"Written by":"TH Author","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.threatshub.org\/blog\/tutorial-how-to-build-your-first-node-js-grpc-api\/#article","isPartOf":{"@id":"https:\/\/www.threatshub.org\/blog\/tutorial-how-to-build-your-first-node-js-grpc-api\/"},"author":{"name":"TH Author","@id":"https:\/\/www.threatshub.org\/blog\/#\/schema\/person\/12e0a8671ff89a863584f193e7062476"},"headline":"Tutorial: How to Build Your First Node.js gRPC API","datePublished":"2022-06-04T00:00:00+00:00","mainEntityOfPage":{"@id":"https:\/\/www.threatshub.org\/blog\/tutorial-how-to-build-your-first-node-js-grpc-api\/"},"wordCount":1858,"publisher":{"@id":"https:\/\/www.threatshub.org\/blog\/#organization"},"image":{"@id":"https:\/\/www.threatshub.org\/blog\/tutorial-how-to-build-your-first-node-js-grpc-api\/#primaryimage"},"thumbnailUrl":"https:\/\/www.threatshub.org\/blog\/coredata\/uploads\/2022\/06\/tutorial-how-to-build-your-first-node-js-grpc-api.jpg","keywords":["Trend Micro DevOps : Article","Trend Micro DevOps : Cloud Native","Trend Micro DevOps : Expert Perspective","Trend Micro DevOps : Multi Cloud","Trend Micro DevOps : Serverless Security"],"articleSection":["TrendMicro"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.threatshub.org\/blog\/tutorial-how-to-build-your-first-node-js-grpc-api\/","url":"https:\/\/www.threatshub.org\/blog\/tutorial-how-to-build-your-first-node-js-grpc-api\/","name":"Tutorial: How to Build Your First Node.js gRPC API 2026 | ThreatsHub Cybersecurity News","isPartOf":{"@id":"https:\/\/www.threatshub.org\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.threatshub.org\/blog\/tutorial-how-to-build-your-first-node-js-grpc-api\/#primaryimage"},"image":{"@id":"https:\/\/www.threatshub.org\/blog\/tutorial-how-to-build-your-first-node-js-grpc-api\/#primaryimage"},"thumbnailUrl":"https:\/\/www.threatshub.org\/blog\/coredata\/uploads\/2022\/06\/tutorial-how-to-build-your-first-node-js-grpc-api.jpg","datePublished":"2022-06-04T00:00:00+00:00","description":"ThreatsHub Cybersecurity News | ThreatsHub.org | Cloud Security & Cyber Threats Analysis Hub. 100% Free OSINT Threat Intelligent and Cybersecurity News.","breadcrumb":{"@id":"https:\/\/www.threatshub.org\/blog\/tutorial-how-to-build-your-first-node-js-grpc-api\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.threatshub.org\/blog\/tutorial-how-to-build-your-first-node-js-grpc-api\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.threatshub.org\/blog\/tutorial-how-to-build-your-first-node-js-grpc-api\/#primaryimage","url":"https:\/\/www.threatshub.org\/blog\/coredata\/uploads\/2022\/06\/tutorial-how-to-build-your-first-node-js-grpc-api.jpg","contentUrl":"https:\/\/www.threatshub.org\/blog\/coredata\/uploads\/2022\/06\/tutorial-how-to-build-your-first-node-js-grpc-api.jpg","width":641,"height":350},{"@type":"BreadcrumbList","@id":"https:\/\/www.threatshub.org\/blog\/tutorial-how-to-build-your-first-node-js-grpc-api\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.threatshub.org\/blog\/"},{"@type":"ListItem","position":2,"name":"Trend Micro DevOps : Article","item":"https:\/\/www.threatshub.org\/blog\/tag\/trend-micro-devops-article\/"},{"@type":"ListItem","position":3,"name":"Tutorial: How to Build Your First Node.js gRPC API"}]},{"@type":"WebSite","@id":"https:\/\/www.threatshub.org\/blog\/#website","url":"https:\/\/www.threatshub.org\/blog\/","name":"ThreatsHub Cybersecurity News","description":"%%focuskw%% Threat Intel \u2013 Threat Intel Services \u2013 CyberIntelligence \u2013 Cyber Threat Intelligence - Threat Intelligence Feeds - Threat Intelligence Reports - CyberSecurity Report \u2013 Cyber Security PDF \u2013 Cybersecurity Trends - Cloud Sandbox \u2013- Threat IntelligencePortal \u2013 Incident Response \u2013 Threat Hunting \u2013 IOC - Yara - Security Operations Center \u2013 SecurityOperation Center \u2013 Security SOC \u2013 SOC Services - Advanced Threat - Threat Detection - TargetedAttack \u2013 APT \u2013 Anti-APT \u2013 Advanced Protection \u2013 Cyber Security Services \u2013 Cybersecurity Services -Threat Intelligence Platform","publisher":{"@id":"https:\/\/www.threatshub.org\/blog\/#organization"},"alternateName":"Threatshub.org","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.threatshub.org\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.threatshub.org\/blog\/#organization","name":"ThreatsHub.org","alternateName":"Threatshub.org","url":"https:\/\/www.threatshub.org\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.threatshub.org\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.threatshub.org\/blog\/coredata\/uploads\/2025\/05\/Threatshub_Favicon1.jpg","contentUrl":"https:\/\/www.threatshub.org\/blog\/coredata\/uploads\/2025\/05\/Threatshub_Favicon1.jpg","width":432,"height":435,"caption":"ThreatsHub.org"},"image":{"@id":"https:\/\/www.threatshub.org\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/threatshub"]},{"@type":"Person","@id":"https:\/\/www.threatshub.org\/blog\/#\/schema\/person\/12e0a8671ff89a863584f193e7062476","name":"TH Author","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/066276f086d5155df79c850206a779ad368418a844da0182ce43f9cd5b506c3d?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/066276f086d5155df79c850206a779ad368418a844da0182ce43f9cd5b506c3d?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/066276f086d5155df79c850206a779ad368418a844da0182ce43f9cd5b506c3d?s=96&d=mm&r=g","caption":"TH Author"}}]}},"_links":{"self":[{"href":"https:\/\/www.threatshub.org\/blog\/wp-json\/wp\/v2\/posts\/46975","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.threatshub.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.threatshub.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.threatshub.org\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.threatshub.org\/blog\/wp-json\/wp\/v2\/comments?post=46975"}],"version-history":[{"count":0,"href":"https:\/\/www.threatshub.org\/blog\/wp-json\/wp\/v2\/posts\/46975\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.threatshub.org\/blog\/wp-json\/wp\/v2\/media\/46976"}],"wp:attachment":[{"href":"https:\/\/www.threatshub.org\/blog\/wp-json\/wp\/v2\/media?parent=46975"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.threatshub.org\/blog\/wp-json\/wp\/v2\/categories?post=46975"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.threatshub.org\/blog\/wp-json\/wp\/v2\/tags?post=46975"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}