{"id":2516,"date":"2025-10-22T10:58:06","date_gmt":"2025-10-22T01:58:06","guid":{"rendered":"https:\/\/www.freelifemakers.org\/wordpress\/?p=2516"},"modified":"2025-10-22T12:54:34","modified_gmt":"2025-10-22T03:54:34","slug":"nodejsnodejs-c","status":"publish","type":"post","link":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/2025\/10\/22\/nodejsnodejs-c\/","title":{"rendered":"[nodejs]Nodejs + Cpp"},"content":{"rendered":"\n<p>\ud83d\udc49\ud83c\udffb Nodejs\uc5d0\uc11c C++ \uc560\ub4dc\uc628(Native Addons)\uc744 \uc0ac\uc6a9\ud558\ub294  \uc774\uc720\ub294 Node.js\uc758\u00a0\uc131\ub2a5 \uc81c\ud55c\uc744 \uadf9\ubcf5\ud558\uace0,\u00a0\uae30\uc874\uc758 C++ \uc0dd\ud0dc\uacc4\uc640 \uc790\uc6d0\uc744 \ud65c\uc6a9\ud558\uae30 \uc704\ud568\uc785\ub2c8\ub2e4. <br>The reason for using C++ addons (Native Addons) in nodejs is to overcome the performance limitations of Node.js and to leverage the existing C++ ecosystem and resources.<\/p>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb \uc544\ub798\ub294 \ub9e5os\uc5d0\uc11c \uc2e4\ud589\ub418\uc5c8\uc2b5\ub2c8\ub2e4.<br>Below was run on macOS.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\"><strong>1.\ucf54\ub4dc\uc791\uc131 \/ Write code<\/strong><\/h5>\n\n\n\n<p>1.1 sersver.js<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ server.js\nconst express = require(\"express\");\nconst app = express();\nconst port = 3000;\n\n\/\/ 1. C++ \uc560\ub4dc\uc628 \ub85c\ub4dc \/ Loading C++ add-ons\n\/\/ node-gyp \ube4c\ub4dc \ud6c4 \uc0dd\uc131\ub418\ub294 .node \ud30c\uc77c\uc758 \uacbd\ub85c\ub97c \uc9c0\uc815\ud569\ub2c8\ub2e4.\n\/\/ Specifies the path to the .node file generated after building node-gyp.\n\/\/ (\ube4c\ub4dc\uac00 \uc131\uacf5\ud558\uba74 build\/Release\/addon_module.node \ud30c\uc77c\uc774 \uc0dd\uc131\ub429\ub2c8\ub2e4.)\n\/\/ (If the build is successful, the build\/Release\/addon_module.node file will be created.)\nconst cppAddon = require(\".\/build\/Release\/addon_module\");\n\napp.use(express.json());\n\n\/\/ 2. C++ \uc560\ub4dc\uc628\uc744 \uc0ac\uc6a9\ud558\ub294 API \uc5d4\ub4dc\ud3ec\uc778\ud2b8 \uc815\uc758\n\/\/    Defining API endpoints using C++ add-ons\napp.get(\"\/calculate\", (req, res) => {\n  \/\/ \ucffc\ub9ac \ud30c\ub77c\ubbf8\ud130\uc5d0\uc11c \ub450 \uc22b\uc790\ub97c \ucd94\ucd9c\n  \/\/ Extract two numbers from query parameters\n  const num1 = parseFloat(req.query.a);\n  const num2 = parseFloat(req.query.b);\n\n  if (isNaN(num1) || isNaN(num2)) {\n    return (\n      res\n        .status(400)\n        \/\/Please enter valid numbers for query parameters 'a' and 'b'.\n        .send(\"\ucffc\ub9ac \ud30c\ub77c\ubbf8\ud130 'a'\uc640 'b'\uc5d0 \uc720\ud6a8\ud55c \uc22b\uc790\ub97c \uc785\ub825\ud558\uc138\uc694.\")\n    );\n  }\n\n  try {\n    \/\/ 3. C++ \uc560\ub4dc\uc628\uc758 \ud568\uc218 \ud638\ucd9c \/ Calling functions in C++ add-ons\n    const result = cppAddon.multiply(num1, num2);\n\n    \/\/ 4. \uacb0\uacfc\ub97c \ud074\ub77c\uc774\uc5b8\ud2b8\uc5d0\uac8c \uc751\ub2f5 \/ Reply the results to the client\n    res.json({\n      input_a: num1,\n      input_b: num2,\n      source: \"C++ Addon\",\n      result: result,\n    });\n  } catch (error) {\n    console.error(\"C++ add-on call error:\", error.message);\n    res.status(500).send(\"Server internal error occurred\");\n  }\n});\n\napp.listen(port, () => {\n  console.log(`Node.js server is running at http:\/\/localhost:${port} .`);\n  console.log(`Test URL: http:\/\/localhost:${port}\/calculate?a=123&amp;b=4.5`);\n});\n<\/code><\/pre>\n\n\n\n<p>1.2 addon.cpp<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ addon.cpp\n\/*\n * \uc774 \ucf54\ub4dc\ub294 \"\ud604\uc7ac Node.js \ud658\uacbd(env)\uc5d0\uc11c C++ \ubcc0\uc218 result\ub97c \uc774\uc6a9\ud558\uc5ec \uc0c8\ub85c\uc6b4 JavaScript \uc22b\uc790 \uac1d\uccb4\ub97c \ub9cc\ub4e4\uc5b4 \ubc18\ud658\ud558\ub77c\"\ub294 \uc758\ubbf8\uac00 \ub429\ub2c8\ub2e4.\n * This code means \"Create a new JavaScript numeric object\n * using the C++ variable result in the current Node.js environment (env) and return it.\"\n *\n * C++ \uc560\ub4dc\uc628\uc740 main\ud568\uc218\uac00 \uc5c6\ub294 \uc774\uc720:Node.js \uc790\uccb4\uc5d0 \uc774\ubbf8 \uac70\ub300\ud55c main \ud568\uc218\uac00 \ud3ec\ud568\ub418\uc5b4 \uc788\uae30 \ub54c\ubb38\uc785\ub2c8\ub2e4.\n * Why C++ addons don't have a main function: Because Node.js itself already contains a huge main function.\n *\n * Napi::Number\ub294 node-addon-api \ub77c\uc774\ube0c\ub7ec\ub9ac\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 C++ \ud074\ub798\uc2a4\ub85c, Node.js \ud658\uacbd\uc5d0\uc11c \ud1b5\uc2e0\ud560 \ub54c JavaScript\uc758 number \ud0c0\uc785\uc744 \ub098\ud0c0\ub0c5\ub2c8\ub2e4.\n * Napi::Number is a C++ class provided by the node-addon-api library that represents the JavaScript number type when communicating in a Node.js environment.\n *\n * Napi::Number \ud074\ub798\uc2a4\ub294 \ub0b4\ubd80\uc801\uc73c\ub85c C++\uc758 \uae30\ubcf8 \uc22b\uc790 \ud0c0\uc785\uc744 JavaScript\uac00 \uc774\ud574\ud558\ub294 \uc22b\uc790 \uac1d\uccb4 \ud3ec\ub9f7\uc73c\ub85c \ubcc0\ud658\ud574 \uc90d\ub2c8\ub2e4.\n * The Napi::Number class internally converts C++'s basic number type into a numeric object format that JavaScript understands.\n*\/\n\n\/\/ C++ \uac1c\ubc1c\uc790\uac00 Node.js\uc758 \uace0\uc131\ub2a5 \ub124\uc774\ud2f0\ube0c \uae30\ub2a5\uc744 \uc0ac\uc6a9\ud558\uae30\uc704\ud55c \ud5e4\ub354\n\/\/ Header for C++ developers to use high-performance native features of Node.js\n#include &lt;napi.h>\n#include &lt;iostream>\n\n\/\/ JavaScript\uc5d0\uc11c \ud638\ucd9c\ub420 C++ \ud568\uc218 \uc815\uc758\n\/\/ Define a C++ function to be called from JavaScript\nNapi::Number Multiply(const Napi::CallbackInfo&amp; info) {\n\n    \/\/ env: \ud604\uc7ac Node.js\uc758 \uc2e4\ud589 \ud658\uacbd(Napi::Env)\uc744 \ub098\ud0c0\ub0c5\ub2c8\ub2e4.\n    \/\/ env: Represents the current Node.js execution environment (Napi::Env).\n    Napi::Env env = info.Env();\n\n    \/\/ \uc778\uc790 \uac1c\uc218 \ud655\uc778 \/ Check number of arguments\n    if (info.Length() &lt; 2 || !info&#91;0].IsNumber() || !info&#91;1].IsNumber()) {\n        Napi::TypeError::New(env, \"\ub450 \uac1c\uc758 \uc22b\uc790\ub97c \uc785\ub825\ud574\uc57c \ud569\ub2c8\ub2e4.\").ThrowAsJavaScriptException();\n        return env.Null().As&lt;Napi::Number>();\n    }\n\n    \/\/ JavaScript \uc778\uc790\ub97c C++ \uc22b\uc790\ub85c \ubcc0\ud658\n    \/\/ Convert JavaScript arguments to C++ numbers\n    double a = info&#91;0].As&lt;Napi::Number>().DoubleValue();\n    double b = info&#91;1].As&lt;Napi::Number>().DoubleValue();\n\n    \/\/ C++ \ub85c\uc9c1 \uc2e4\ud589\n    \/\/ Execute C++ logic\n    double result = a * b;\n    std::cout &lt;&lt; \"C++ \uc560\ub4dc\uc628\uc5d0\uc11c \uacf1\uc148 \ub85c\uc9c1 \uc2e4\ud589\ub428: \" &lt;&lt; a &lt;&lt; \" * \" &lt;&lt; b &lt;&lt; std::endl;\n\n    \/\/ \uacb0\uacfc\ub97c JavaScript Number \ud0c0\uc785\uc73c\ub85c \ubcc0\ud658\ud558\uc5ec \ubc18\ud658\n    \/\/ Convert the result to JavaScript Number type and return it\n    \/\/ New()\ub294 \uc0c8\ub85c\uc6b4 JavaScript \uac1d\uccb4\ub97c \uc0dd\uc131\ud558\ub294 \uba54\uc11c\ub4dc\n    \/\/ New() is a method that creates a new JavaScript object.\n    return Napi::Number::New(env, result);\n}\n\n\/\/ \ubaa8\ub4c8 \ucd08\uae30\ud654 (exports \uac1d\uccb4\uc5d0 \ud568\uc218 \ub4f1\ub85d)\n\/\/ Initialize module (register functions in exports object)\nNapi::Object Init(Napi::Env env, Napi::Object exports) {\n    exports.Set(\n        \/\/ \uc790\ubc14\uc2a4\ud06c\ub9bd\ud2b8\uc5d0\uc11c addon.multiply(a, b);\ub85c \uc0ac\uc6a9\ub428.\n        \/\/ Used in JavaScript as addon.multiply(a, b);\n        Napi::String::New(env, \"multiply\"),\n\n        \/\/ Function\ud0c0\uc785\uc740 \uc790\ubc14\uc2a4\ud06c\ub9bd\ud2b8\uc5d0\uc11c \ud568\uc218\ub85c \uc0ac\uc6a9 \ud560 \uc218 \uc788\uac8c \ud574\uc90c.\n        \/\/ The Function type allows you to use it as a function in JavaScript.\n        \/\/ \uc2e4\uc81c\ub85c \uc2e4\ud589\ub420 c++ \ud568\uc218\uc785\ub2c8\ub2e4. \/ This is the c++ function that will actually be executed.\n        Napi::Function::New(env, Multiply)\n    );\n    return exports;\n}\n\n\/\/ Node.js \ubaa8\ub4c8\ub85c \ub4f1\ub85d\n\/\/ Register as a Node.js module\nNODE_API_MODULE(NODE_GYP_MODULE_NAME, Init)\n<\/code><\/pre>\n\n\n\n<p>1.3 binding.gyp<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># GYP (Generate Your Projects): \uc774 \ud615\uc2dd\uc740 Google\uc5d0\uc11c \uac1c\ubc1c\ub418\uc5c8\uc73c\uba70,\n# \uc6d0\ub798\ub294 Chromium \ud504\ub85c\uc81d\ud2b8\ub97c \uc704\ud574 \uc0ac\uc6a9\ub418\uc5c8\uc2b5\ub2c8\ub2e4.\n# \uc774\ub294 \ub2e4\uc591\ud55c \ud50c\ub7ab\ud3fc(macOS, Linux, Windows)\uc5d0\uc11c C++ \ud504\ub85c\uc81d\ud2b8\ub97c \ube4c\ub4dc\ud558\uae30 \uc704\ud55c \ube4c\ub4dc \uc2dc\uc2a4\ud15c \uc124\uc815 \uc5b8\uc5b4\uc785\ub2c8\ub2e4.\n\n# GYP (Generate Your Projects): This format was developed by Google and was originally used for the Chromium project.\n# It is a build system configuration language for building C++ projects on various platforms (macOS, Linux, Windows).\n\n# binding.gyp\n{\n  \"targets\": &#91;\n    {\n      # target_name : \ucd5c\uc885\uc801\uc73c\ub85c \uc0dd\uc131\ub420 .node \ud30c\uc77c\uc758 \uc774\ub984 \/ The name of the .node file that will ultimately be created\n      # sources : \ube4c\ub4dc\ud560 \uc18c\uc2a4 \ucf54\ub4dc \ud30c\uc77c \ubaa9\ub85d\uc744 \uc9c0\uc815\ud569\ub2c8\ub2e4. \/ Specifies a list of source code files to build.\n      # include_dirs : C++ \ucf54\ub4dc\uc5d0\uc11c #include &lt;napi.h>\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub3c4\ub85d \ud569\ub2c8\ub2e4. \/ Enables you to use #include &lt;napi.h> in your C++ code.\n\n      \"target_name\": \"addon_module\",\n      \"sources\": &#91; \"addon.cpp\" ],\n      \"include_dirs\": &#91;\n        \"&lt;!@(node -p \\\"require('node-addon-api').include\\\")\"\n      ],\n      \"defines\": &#91; \"NAPI_CPP_EXCEPTIONS\" ],\n\n      # C++ \ucef4\ud30c\uc77c\ub7ec \ud50c\ub798\uadf8 \uc124\uc815: \uc608\uc678 \ucc98\ub9ac \ud65c\uc131\ud654 \/ Setting C++ Compiler Flags: Enable Exception Handling\n      # -- C++\uc758 \ud575\uc2ec \uae30\ub2a5\uc778 try, catch, throw \uad6c\ubb38\uc774 \ucef4\ud30c\uc77c\ub418\uc5b4 \ub7f0\ud0c0\uc784\uc5d0 \uc81c\ub300\ub85c \uc791\ub3d9\ud560 \uc218 \uc788\ub3c4\ub85d \ub9cc\ub4ed\ub2c8\ub2e4.\n      #    The try, catch, and throw statements, which are core features of C++, are compiled so that they work properly at runtime.\n\n      \"cflags_cc\": &#91;\n          \"-fexceptions\"\n      ],\n\n      # (macOS \uc804\uc6a9) XCode\/Darwin \ube4c\ub4dc \uc124\uc815 \uc624\ubc84\ub77c\uc774\ub4dc\n      # (macOS only) Override XCode\/Darwin build settings\n\n      # \uc608\uc678\ucc98\ub9ac \uae30\ub2a5\uc774 \ube44\ud65c\uc131\ud654\ub418\uba74 \uc624\ub958\uac00 \ubc1c\uc0dd\ud569\ub2c8\ub2e4.\n      # \uc544\ub798\uc758 \ucf54\ub4dc\ub294 \ub9e5os\uc758 \uc608\uc678\ucc98\ub9ac \uae30\ub2a5\uc744 \ud65c\uc131\ud654\ud558\ub294 \ucf54\ub4dc \uc785\ub2c8\ub2e4.\n      # An error will occur if exception handling is disabled.\n      # The code below enables exception handling in macOS.\n\n      'xcode_settings': {\n          'GCC_ENABLE_CPP_EXCEPTIONS': 'YES', # C++ \uc608\uc678 \ud65c\uc131\ud654\n          'OTHER_CPLUSPLUSFLAGS': &#91; '-fexceptions' ] # \ucd94\uac00 \ud50c\ub798\uadf8\n      },\n\n      # \uc548\uc804\uc744 \uc704\ud574 \uae30\ubcf8 -fno-exceptions\ub97c \uc81c\uac70 (\ub9cc\uc57d node-gyp \uae30\ubcf8 \uc124\uc815\uc5d0 \uc788\ub2e4\uba74)\n      # Remove default -fno-exceptions for safety (if it's in node-gyp default config)\n\n      # cflags! : C \ucef4\ud30c\uc77c\ub7ec\uc758 \uc608\uc678 \ube44\ud65c\uc131\ud654 \uc635\uc158 \uc81c\uac70 \/ Removed the option to disable exceptions from the C compiler.\n      # cflags_cc! : C++ \ucef4\ud30c\uc77c\ub7ec\uc758 \uc608\uc678 \ube44\ud65c\uc131\ud654 \uc635\uc158 \uc81c\uac70 \/ Removed the option to disable exceptions from the C++ compiler.\n\n      \"cflags!\": &#91; \"-fno-exceptions\" ],\n      \"cflags_cc!\": &#91; \"-fno-exceptions\" ]\n    }\n  ]\n}\n<\/code><\/pre>\n\n\n\n<h5 class=\"wp-block-heading\">2.1.\uc758\uc874\uc131 \uc124\uce58 \/ install dependencies<\/h5>\n\n\n\n<pre class=\"wp-block-code\"><code>npm install node-gyp node-addon-api express --save<\/code><\/pre>\n\n\n\n<p>2.2.C++ \uc560\ub4dc\uc628 \ube4c\ub4dc \/ C++ add-on build<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npx node-gyp configure\nnpx node-gyp build<\/code><\/pre>\n\n\n\n<p>2.3.\uc11c\ubc84\uc2e4\ud589 \/ server run<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>node server.js<\/code><\/pre>\n\n\n\n<p>2.4 \ud130\ubbf8\ub110\uc5d0\uc11c \ud14c\uc2a4\ud2b8 \/ Test in terminal<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl http:\/\/localhost:3000\/calculate?a=123&amp;b=4.5<\/code><\/pre>\n\n\n\n<p>2.5 \ube0c\ub77c\uc6b0\uc800 \ud14c\uc2a4\ud2b8 \uacb0\uacfc \/ Browser test results<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"input_a\": 123,\n  \"input_b\": 4.5,\n  \"source\": \"C++ Addon\",\n  \"result\": 553.5\n}<\/code><\/pre>\n\n\n\n<h5 class=\"wp-block-heading\">3. \uc2e4\ud589 \/ Run<\/h5>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"658\" src=\"https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2025\/10\/1-1-1024x658.png\" alt=\"\" class=\"wp-image-2535\" srcset=\"https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2025\/10\/1-1-1024x658.png 1024w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2025\/10\/1-1-300x193.png 300w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2025\/10\/1-1-768x494.png 768w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2025\/10\/1-1.png 1136w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"500\" src=\"https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2025\/10\/2-1024x500.png\" alt=\"\" class=\"wp-image-2536\" srcset=\"https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2025\/10\/2-1024x500.png 1024w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2025\/10\/2-300x147.png 300w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2025\/10\/2-768x375.png 768w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2025\/10\/2.png 1408w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h5 class=\"wp-block-heading\">4.\uc124\uc815\ud30c\uc77c\uc744 \uc218\uc815\ud55c \uacbd\uc6b0 \/ If you have modified the settings file<\/h5>\n\n\n\n<p>4.1 \ube4c\ub4dc\ud30c\uc77c\uc815\ub9ac \/ Build file organization<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npx node-gyp clean<\/code><\/pre>\n\n\n\n<p>4.2 \uad6c\uc131 \uc7ac\uc2e4\ud589 \/ Rerun configuration<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npx node-gyp configure<\/code><\/pre>\n\n\n\n<p>4.3 \ube4c\ub4dc \uc7ac\uc2e4\ud589 \/ Rerun the build<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npx node-gyp build<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>\ud83d\udc49\ud83c\udffb Nodejs\uc5d0\uc11c C++ \uc560\ub4dc\uc628(Native Addons)\uc744 \uc0ac\uc6a9\ud558\ub294 \uc774\uc720\ub294 Node.js\uc758\u00a0\uc131\ub2a5 \uc81c\ud55c\uc744 \uadf9\ubcf5\ud558\uace0,\u00a0\uae30\uc874\uc758 C++ \uc0dd\ud0dc\uacc4\uc640 \uc790\uc6d0\uc744 \ud65c\uc6a9\ud558\uae30 \uc704\ud568\uc785\ub2c8\ub2e4. The reason for using C++ addons (Native Addons) in nodejs is to overcome the performance limitations of Node.js and to leverage the existing C++ ecosystem and resources. \ud83d\udc49\ud83c\udffb \uc544\ub798\ub294 \ub9e5os\uc5d0\uc11c \uc2e4\ud589\ub418\uc5c8\uc2b5\ub2c8\ub2e4.Below was run on macOS. 1.\ucf54\ub4dc\uc791\uc131 \/ Write code 1.1 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9,1],"tags":[],"class_list":["post-2516","post","type-post","status-publish","format-standard","hentry","category-nodejs","category-uncategorized","missing-thumbnail"],"_links":{"self":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/2516","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/comments?post=2516"}],"version-history":[{"count":21,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/2516\/revisions"}],"predecessor-version":[{"id":2539,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/2516\/revisions\/2539"}],"wp:attachment":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/media?parent=2516"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/categories?post=2516"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/tags?post=2516"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}