{"id":3468,"date":"2022-08-25T09:30:00","date_gmt":"2022-08-25T13:30:00","guid":{"rendered":"https:\/\/www.redline13.com\/blog\/?page_id=3468"},"modified":"2022-08-28T23:48:16","modified_gmt":"2022-08-29T03:48:16","slug":"custom-load-test-nodejs","status":"publish","type":"page","link":"https:\/\/www.redline13.com\/blog\/custom-load-test-nodejs\/","title":{"rendered":"Custom Load Tests using NodeJS"},"content":{"rendered":"<h3>Writing Custom Load Tests<\/h3>\n<p>Custom load tests allow the greatest degree of freedom and flexibility on our platform.\u00a0 Some things that are shared between any of our supported language-specific load tests are:<\/p>\n<ul>\n<li>The ability to run <em>any<\/em> code you want to execute<\/li>\n<li>RedLine13 <a href=\"https:\/\/www.redline13.com\/ApiDoc\">API<\/a> calls can report test execution and timing<\/li>\n<\/ul>\n<p>Each language is documented independently and can be found on the corresponding page using the links below:<\/p>\n<ul>\n<li><a href=\"https:\/\/www.redline13.com\/blog\/custom-load-test-php\/\">PHP<\/a><\/li>\n<li><a href=\"https:\/\/www.redline13.com\/blog\/custom-load-test-nodejs\/\">NodeJS<\/a><\/li>\n<li><a href=\"https:\/\/www.redline13.com\/blog\/custom-load-test-python\/\">Python<\/a><\/li>\n<\/ul>\n<h3>Choosing your Language<\/h3>\n<p>There are several factors which will drive your decision on which supported language to use for your custom load test (<em>e.g.<\/em>, PHP, NodeJS, or Python).\u00a0 One of the primary reasons you may choose to write a custom load test in the first place is to have ultimate control and flexibility over your test.\u00a0 You can achieve this with any of the supported languages.\u00a0 However, no matter which one you select the next factor would be your relative familiarity with each of these languages.\u00a0 In this post we will focus on writing a custom NodeJS test, but the concepts on our platform will generally carry over into the other supported languages.<\/p>\n<h3>Submitting\u00a0Performance Tests<\/h3>\n<ul>\n<li>There are two ways to submit a custom load test\n<ul>\n<li>Submit the Load Test File (<em>e.g.<\/em>, <code>[ANY_NAME].js<\/code>) in the language specified.<\/li>\n<li>Submit a compressed file (which can be <code>.tar<\/code>, <code>tar.gz<\/code>, or <code>.tgz<\/code>) with the custom file specifically named.\u00a0 For <a href=\"https:\/\/nodejs.org\/en\/docs\/\">NodeJS<\/a> tests this is &#8220;<code>CustomTest.js<\/code>&#8220;.<\/li>\n<\/ul>\n<\/li>\n<li>Custom Load Tests support <a href=\"https:\/\/en.wikipedia.org\/wiki\/Comma-separated_values\">CSV<\/a> files, compressed archives, and extra files as attachments:\n<ul>\n<li>CSV files can be split across servers using the &#8220;<em>split<\/em>&#8221; option.<\/li>\n<li>Compressed files can be marked to be expanded using the &#8220;<em>expand<\/em>&#8221; option.<\/li>\n<li>All files are placed in the root of the load test.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h3>Package Support in Load Tests<\/h3>\n<p>Each Language supports a packaging mechanism to install more packages.\u00a0 For NodeJS, <span style=\"color: initial;\"><a href=\"https:\/\/docs.npmjs.com\/\">NPM<\/a> is built into the test, so you just need to include your own <\/span><code>package.json<\/code><span style=\"color: initial;\">\u00a0and we will run <\/span><code>npm install<\/code><span style=\"color: initial;\">.<\/span><\/p>\n<h3>Versioning<\/h3>\n<p>Using the Node Version Manger (<a href=\"https:\/\/github.com\/nvm-sh\/nvm\">NVM<\/a>), our <a href=\"https:\/\/www.redline13.com\/blog\/2016\/07\/node-version-manager-plugin\/\">Node Version Manager Plugin<\/a> supports all version of NodeJS.<\/p>\n<h3>Test Harness for local testing<\/h3>\n<p>A Test Harness is available for all languages, including examples for the <a href=\"https:\/\/github.com\/redline13\/harness-custom-test-nodejs\">NodeJS Harness<\/a>.\u00a0 If you are writing a custom test in a different language (such as PHP or Python), you will want to select the appropriate test harness as described above.<\/p>\n<h2 id=\"phptest\">NodeJS\u00a0Test<\/h2>\n<p>To write a custom load test in Node.js, you need to create a Node.js file named <code>CustomTest.js<\/code>\u00a0if packaged in compressed file, otherwise it can be any name.<\/p>\n<p>You can\u00a0include the helper class <code>loadTestingSession<\/code> for testing HTTP requests. \u00a0This class helps to manage cookies and track performance data.\u00a0 The following code snippet illustrates how to add this:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">var LoadTestingSession = require(\".\/loadTestingSession.js\");<\/pre>\n<p>You will need to define a function constructor with the arguments \u00a0<code>(redlineApi, testNum, rand, config)<\/code>.\u00a0 Here is an example constructor definition:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">\/**\n * Build a custom test by creating a constructor\n * @param redlineAPI - redline metric calls\n * @param testNum - when simulating many users, this is the user number\n * @param rand - a test identifier, same across all users within test\n * @param config - hashmap for your config variables passed through\n *\/\nfunction MyCustomTest(redlineApi, testNum, rand, config)\n{\n    ...\n}<\/pre>\n<p>An explanation of the corresponding constructor arguments above are as follows:<\/p>\n<ul>\n<li><code>redlineApi<\/code> \u2013 This variable will let you access Redline API methods to report back data.<\/li>\n<li><code>testNum<\/code> \u2013 This is the test number that is being run.<\/li>\n<li><code>rand<\/code> \u2013 This is a random string associated with the test that typically is unused.<\/li>\n<li><code>config<\/code> \u2013 This is the parsed result of <a href=\"https:\/\/npmjs.org\/package\/ini\"><code>ini.parse<\/code><\/a>. <code>config.load_resources<\/code> will be set to <code>\"1\"<\/code> if you enabled the associated setting when starting the test.<\/li>\n<\/ul>\n<p>The test does not start when the constructor is called. \u00a0However, here we can setup variables for this instance of the test and read configuration. \u00a0Here is an example which accomplishes this:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">function MyCustomTest(redlineApi, testNum, rand, config)\n{\n  \/\/ We need Redline API to report results, errors, requests.\n  this.redlineApi = redlineApi;\n\n  \/\/ Keep track of test information.\n  this.testNum = testNum;\n  this.rand = rand;\n\n  \/\/ This is the test configuration file (loadtest.ini)\n  this.config = config;\n\n  \/\/ Hardcode endpoint, requires plugin to customize.\n  this.url = this.config.url;\n  if ( !this.url )\n    this.url = \"https:\/\/httpbin.org\/status\/200\";\n\n  \/\/ This is just example, you might need build a redline plugin to add these parameters.\n  this.minDelayMs = this.config.min | 500;\n  this.maxDelayMs = this.config.max | 10000;\n}<\/pre>\n<p>As such, the test starts when <code>runTest<\/code> is called on the class. \u00a0This method accepts a callback function that expects a single parameter that is <code>true<\/code> if the test failed and <code>false<\/code> otherwise.\u00a0 The callback can be called using <code>callback.call(that, failed);<\/code>.\u00a0 Here is an example of that:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"null\">\/** \n * Run test \n * @param redlineCallback as tests are asynch callback is used to tell runner that test is complete (success or failure) \n *\/\nMyCustomTest.prototype.runTest = function( redlineCallback )\n{\n    ...\n}<\/pre>\n<p>Inside your test, it&#8217;s all your code and work. \u00a0You can use the <code>redlineApi<\/code> class to tell RedLine13 the performance data to track:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">MyCustomTest.prototype.runTest = function( redlineCallback )\n{\n  var that = this;\n\n  \/\/ Set delay\n  var delay = 1;\n  if (this.delayRangeMs != 0)\n    delay = Math.floor((Math.random()*this.delayRangeMs)+this.minDelayMs);\n  \/\/ delay = 1;\n\n  \/\/ Make request after timeout\n  console.log(\"Making request to \" + that.url + \" in \" + delay + \"ms.\");\n  setTimeout(function() {\n    try\n    {\n      \/\/ Helper function make HTTP Request.,  source @ https:\/\/github.com\/redline13\/harness-custom-test-nodejs\/blob\/master\/CustomTestSimple.js#L78\n      that.loadPage(that.url, function( failed ) {\n        \/\/ Iteration complete\n        that.remainingIterations--;\n\n        \/\/ Another iteration?\n        if (!failed &amp;&amp; that.remainingIterations &gt; 0)\n          that.runTest(redlineCallback);\n        else\n          \/\/ Callback\n          redlineCallback(failed, 'on-load-page' );\n      });\n    } catch (e) {\n      \/\/ Callback\n      console.log(e);\n      that.redlineApi.recordError(\"\"+e + (e.stack ? \"\\n\" + e.stack : \"\"));\n      redlineCallback(true, 'on-exception' );\n    }\n  }, delay);\n};<\/pre>\n<p>This file should export a class using <code>module.exports = YourCustomTestClassName;<\/code>.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">\/\/ Required Export for Test to be loaded and executed.\nmodule.exports = MyCustomTest;\n<\/pre>\n<p>An instance of this class will be started for each user specified in the \u201c<em>Number of User<\/em>\u201d form field. To save CPU usage on the load agents, each Node.js process will run multiple tests (<em>i.e.<\/em>, will instantiate multiple instances of your class).\u00a0 This is important if you are using any global variables as they could be shared, best to keep things at the scope of the instance.<\/p>\n<h3>Packaging your test<\/h3>\n<p>A test can be just uploaded for quick testing, however you should create a <code>.tar<\/code> or <code>.tgz<\/code> file that contains <code>CustomTest.js<\/code> and optionally <code>package.json<\/code> in the root directory.\u00a0 This is the file that should be uploaded to start the test.\u00a0 The <code>package.json<\/code> file will be used prior to the test with <code>npm install package.json<\/code> to install any extra libraries you may need.\u00a0 You can also include other helper classes in the tar file.<\/p>\n<h3>Recording methods\u00a0available<\/h3>\n<p>The RedLine13 <a href=\"https:\/\/www.redline13.com\/ApiDoc\">API<\/a> contains the following methods:<\/p>\n<ul>\n<li><code class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">redlineApi.recordPageTime(ts, time)<\/code> &#8211; This records and aggregates the total page load time for a request, with <code>ts<\/code> being the UNIX timestamp when the request started and <code>time<\/code> being the time to complete the request. This function is used in the UI to report the overall average response time. The <code>goToUrl<\/code> method of <code>LoadTestingSession<\/code> calls this for you.<\/li>\n<li><code class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">redlineApi.recordURLPageLoad(url, ts, time, err, kb, rc, user)<\/code> &#8211; This records and aggregates the total page load time for a request to a specific URL, with <code>ts<\/code> being the UNIX timestamp when the request started and <code>time<\/code> being the time to complete the request.\u00a0 You can also pass in <code>err<\/code> to record an error and <code>kb<\/code> to record the number of kilobytes downloaded.\u00a0 The response code can be specified using <code>rc<\/code>, and the user identifier can be passed as <code>user<\/code>. \u00a0This function is used in the UI to report the per page average response time but does not affect the overall response time that is calculated.\u00a0 The <code>goToUrl<\/code> and <code>loadResources<\/code> methods of<code>LoadTestingSession<\/code> calls this for you.<\/li>\n<li><code class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">redlineApi.recordDownloadSize(kb)<\/code> &#8211; This records the number of kilobytes downloaded for a request. The <code>goToUrl<\/code> and <code>loadResources<\/code> methods of <code>LoadTestingSession<\/code> calls this for you.<\/li>\n<li><code class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">redlineApi.recordError(error)<\/code> &#8211; This records an error that will be displayed in the UI.<\/li>\n<li><code class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">redlineApi.recordProgress(testNum, percent)<\/code> &#8211; This records the progress (between <code>0<\/code> and <code>100<\/code>) of a single test. This allows you to enable more accurate progress than the default, which is based only on the number completed <em>vs<\/em>. the test size.<\/li>\n<\/ul>\n<h4>LoadTestingSession Helper Class<\/h4>\n<p>You may wish to use the included <code>LoadTestingSession(testNum, redlineApi, loadResources)<\/code> class.\u00a0 Simply call the constructor and then call <code>loadPage<\/code>, passing in a callback function.\u00a0 The callback will receive a single parameter of <code>true<\/code> if the test failed and <code>false<\/code> otherwise.<\/p>\n<h3>Tips<\/h3>\n<ul>\n<li>To make better use of NodeJs\u00a0and invoke test in <em>Async<\/em> use a <code>setTimeout<\/code> <span class=\"pl-c1\">call, as shown in the example above.<\/span><\/li>\n<li>You can use the random string that is passed in as the second parameter to your <code>CustomTest<\/code> constructor to append to URLs.\u00a0 This can help you to easily identify load testing requests in your server logs.<\/li>\n<li>If you need additional resources for your test, you can download a file (<em>e.g.<\/em>, a <code>.tgz<\/code> file) with the resources in the <code>CustomTest<\/code> constructor.\u00a0 You should include code to ensure that only one test per server downloads the files.\u00a0 If you know the number of tests per server, you can use the test number to decide which test should download the files.\u00a0 Alternatively, you can attempt to create a lock file, with the first process successfully creating the lock file doing the file download.<\/li>\n<\/ul>\n<h3 id=\"nodetest\">Complete Examples<\/h3>\n<p>You can find an example <a href=\"https:\/\/github.com\/redline13\/harness-custom-test-nodejs\/blob\/master\/CustomTestSimple.js\">CustomTestSimple.js<\/a>, which performs a Simple URL test with echo.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Writing Custom Load Tests Custom load tests allow the greatest degree of freedom and flexibility on our platform.\u00a0 Some things that are shared between any of our supported language-specific load tests are: The ability to run any code you want to execute RedLine13 API calls can report test execution and timing Each language is documented independently and can be found on the corresponding page using the links below: PHP NodeJS Python Choosing your Language There are<a class=\"more-link\" href=\"https:\/\/www.redline13.com\/blog\/custom-load-test-nodejs\/\">Read More &rarr;<\/a><\/p>\n","protected":false},"author":1,"featured_media":3471,"parent":0,"menu_order":9,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":{"0":"entry","1":"page","2":"publish","3":"author-user","4":"post-3468","6":"has-post-thumbnail"},"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v20.12 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Custom Load Tests using NodeJS - RedLine13<\/title>\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.redline13.com\/blog\/custom-load-test-nodejs\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Custom Load Tests using NodeJS - RedLine13\" \/>\n<meta property=\"og:description\" content=\"Writing Custom Load Tests Custom load tests allow the greatest degree of freedom and flexibility on our platform.\u00a0 Some things that are shared between any of our supported language-specific load tests are: The ability to run any code you want to execute RedLine13 API calls can report test execution and timing Each language is documented independently and can be found on the corresponding page using the links below: PHP NodeJS Python Choosing your Language There areRead More &rarr;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.redline13.com\/blog\/custom-load-test-nodejs\/\" \/>\n<meta property=\"og:site_name\" content=\"RedLine13\" \/>\n<meta property=\"article:modified_time\" content=\"2022-08-29T03:48:16+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2016\/10\/nodejslogo.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1280\" \/>\n\t<meta property=\"og:image:height\" content=\"640\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.redline13.com\/blog\/custom-load-test-nodejs\/\",\"url\":\"https:\/\/www.redline13.com\/blog\/custom-load-test-nodejs\/\",\"name\":\"Custom Load Tests using NodeJS - RedLine13\",\"isPartOf\":{\"@id\":\"https:\/\/www.redline13.com\/blog\/#website\"},\"datePublished\":\"2022-08-25T13:30:00+00:00\",\"dateModified\":\"2022-08-29T03:48:16+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.redline13.com\/blog\/custom-load-test-nodejs\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.redline13.com\/blog\/custom-load-test-nodejs\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.redline13.com\/blog\/custom-load-test-nodejs\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.redline13.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Custom Load Tests using NodeJS\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.redline13.com\/blog\/#website\",\"url\":\"https:\/\/www.redline13.com\/blog\/\",\"name\":\"RedLine13\",\"description\":\"(Almost) Free Load Testing in the Cloud\",\"publisher\":{\"@id\":\"https:\/\/www.redline13.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.redline13.com\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.redline13.com\/blog\/#organization\",\"name\":\"RedLine13\",\"url\":\"https:\/\/www.redline13.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.redline13.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2013\/06\/cropped-rl13-header-logo.jpg\",\"contentUrl\":\"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2013\/06\/cropped-rl13-header-logo.jpg\",\"width\":300,\"height\":68,\"caption\":\"RedLine13\"},\"image\":{\"@id\":\"https:\/\/www.redline13.com\/blog\/#\/schema\/logo\/image\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Custom Load Tests using NodeJS - RedLine13","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.redline13.com\/blog\/custom-load-test-nodejs\/","og_locale":"en_US","og_type":"article","og_title":"Custom Load Tests using NodeJS - RedLine13","og_description":"Writing Custom Load Tests Custom load tests allow the greatest degree of freedom and flexibility on our platform.\u00a0 Some things that are shared between any of our supported language-specific load tests are: The ability to run any code you want to execute RedLine13 API calls can report test execution and timing Each language is documented independently and can be found on the corresponding page using the links below: PHP NodeJS Python Choosing your Language There areRead More &rarr;","og_url":"https:\/\/www.redline13.com\/blog\/custom-load-test-nodejs\/","og_site_name":"RedLine13","article_modified_time":"2022-08-29T03:48:16+00:00","og_image":[{"width":1280,"height":640,"url":"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2016\/10\/nodejslogo.png","type":"image\/png"}],"twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.redline13.com\/blog\/custom-load-test-nodejs\/","url":"https:\/\/www.redline13.com\/blog\/custom-load-test-nodejs\/","name":"Custom Load Tests using NodeJS - RedLine13","isPartOf":{"@id":"https:\/\/www.redline13.com\/blog\/#website"},"datePublished":"2022-08-25T13:30:00+00:00","dateModified":"2022-08-29T03:48:16+00:00","breadcrumb":{"@id":"https:\/\/www.redline13.com\/blog\/custom-load-test-nodejs\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.redline13.com\/blog\/custom-load-test-nodejs\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.redline13.com\/blog\/custom-load-test-nodejs\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.redline13.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Custom Load Tests using NodeJS"}]},{"@type":"WebSite","@id":"https:\/\/www.redline13.com\/blog\/#website","url":"https:\/\/www.redline13.com\/blog\/","name":"RedLine13","description":"(Almost) Free Load Testing in the Cloud","publisher":{"@id":"https:\/\/www.redline13.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.redline13.com\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.redline13.com\/blog\/#organization","name":"RedLine13","url":"https:\/\/www.redline13.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.redline13.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2013\/06\/cropped-rl13-header-logo.jpg","contentUrl":"https:\/\/www.redline13.com\/blog\/wp-content\/uploads\/2013\/06\/cropped-rl13-header-logo.jpg","width":300,"height":68,"caption":"RedLine13"},"image":{"@id":"https:\/\/www.redline13.com\/blog\/#\/schema\/logo\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/www.redline13.com\/blog\/wp-json\/wp\/v2\/pages\/3468","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.redline13.com\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.redline13.com\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.redline13.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.redline13.com\/blog\/wp-json\/wp\/v2\/comments?post=3468"}],"version-history":[{"count":6,"href":"https:\/\/www.redline13.com\/blog\/wp-json\/wp\/v2\/pages\/3468\/revisions"}],"predecessor-version":[{"id":10030,"href":"https:\/\/www.redline13.com\/blog\/wp-json\/wp\/v2\/pages\/3468\/revisions\/10030"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.redline13.com\/blog\/wp-json\/wp\/v2\/media\/3471"}],"wp:attachment":[{"href":"https:\/\/www.redline13.com\/blog\/wp-json\/wp\/v2\/media?parent=3468"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}