{"id":513,"date":"2018-06-05T00:34:29","date_gmt":"2018-06-04T23:34:29","guid":{"rendered":"https:\/\/marketaylor.synology.me\/?p=513"},"modified":"2019-11-24T14:59:11","modified_gmt":"2019-11-24T14:59:11","slug":"easier-use-of-the-node-js-interface-for-mq","status":"publish","type":"post","link":"https:\/\/marketaylor.synology.me\/?p=513","title":{"rendered":"Easier use of the Node.js interface for MQ"},"content":{"rendered":"<p>In November, <a href=\"https:\/\/marketaylor.synology.me\/?p=505\" target=\"_blank\" rel=\"noopener noreferrer\">I wrote<\/a> about a new language binding to MQ, making it possible to use Javascript in a Node.JS environment to access the MQ API. I published the first release of that code only through <a href=\"http:\/\/github.com\/ibm-messaging\/mq-mqi-nodejs\" target=\"_blank\" rel=\"noopener noreferrer\">GitHub<\/a> which required that you clone it locally before you could use it. Once the initial public exposure proved some stability to the interface, I added the ibmmq package to the <a href=\"https:\/\/www.npmjs.com\/package\/ibmmq\">npm repository<\/a> meaning that you could simply refer to it in the descriptors (package.json) for your programs and npm would automatically download and install it.<\/p>\n<p>But there was still one drawback. The package builds on, and requires, the MQ C client runtime libraries. That needed a separate operation to complete the installation, as those libraries came from product installation media or required you to login to an authorised location before they could be accessed.<\/p>\n<p>No longer though.<\/p>\n<p>Recent updates to the MQ Redistributable Client package and then to the MQ Node.js component have made it much simpler to get an MQ application running, and to create standalone containers for those applications.<\/p>\n<p><!--more--><\/p>\n<h2>The MQ Redistributable Client<\/h2>\n<p>This package was designed to make it possible to embed the essential MQ runtime files alongside an application, making it possible to distribute a standalone resource.<\/p>\n<p>Jon Rumsey wrote more about it <a href=\"https:\/\/www.ibm.com\/developerworks\/community\/blogs\/messaging\/entry\/Bitesize_Blogging_MQ_8_0_0_4_Redistributable_Clients\">here<\/a>.<\/p>\n<p>The two primary application platforms \u2013 Linux x64 and Windows \u2013 are supported by this component.<\/p>\n<p>Earlier this year, the latest versions of the Redistributable Client were put into the same public repository as the full MQ Advanced Server for Developers product. That makes it possible to download the file directly without needing any login credentials. (The corresponding solution for the Java variant of the Redistributable Client was to put it on the <a href=\"https:\/\/developer.ibm.com\/messaging\/2018\/01\/09\/developing-mq-java-applications-maven\/\">Maven Central Repository<\/a>.)<\/p>\n<h2>Automatic installation with the Node.js package<\/h2>\n<p>The MQ Node.js package now exploits that easy access to the C runtime to download it as part of its own installation.<\/p>\n<p>When you write a Node.js program, the description of the program in <em>package.json<\/em> lists which other packages are required. Running <code>npm install<\/code> for your application tries to download those prerequisite packages (and their dependencies) from the npm repository. Part of the ibmmq package includes directives (also written in JavaScript) for a postinstall step that pulls down that tar or zip file during the npm installation process. The postinstall code then unpacks the image and deletes many of the files, leaving just the pieces needed for actually running a C application.<br \/>\nFor example, using one of the sample programs included with this package, and creating a basic package file:<\/p>\n<pre>$ cat package.json\n{\n  \"name\": \"amqsput\",\n  \"version\": \"0.0.1\",\n  \"description\": \"For demonstrating automatic installation of MQ API\",\n  \"main\": \"amqsput.js\",\n  \"dependencies\": {\n    \"ibmmq\": \"&gt;=0.7.0\"\n  }\n}\n<\/pre>\n<p>Then running the installation step, which shows the download of the C libraries:<\/p>\n<pre>$ npm install\n... (various messages showing installation of other pieces) ...\n&gt; ibmmq@0.7.0 postinstall \/tmp\/nodetest\/node_modules\/ibmmq\n&gt; node postinstall.js\n\n<strong>Downloading  IBM MQ Redistributable C Client runtime libraries - version 9.0.5.0<\/strong>\n<strong>Unpacking libraries...<\/strong>\nRemoving 9.0.5.0-IBM-MQC-Redist-LinuxX64.tar.gz\namqsput@0.0.1 \/tmp\/nodetest\n\u2514\u2500\u252c ibmmq@0.7.0\n\u251c\u2500\u252c ffi@2.2.0\n\u2502 \u251c\u2500\u2500 bindings@1.2.1\n\u2502 \u251c\u2500\u252c debug@2.6.9\n... (more about the dependency tree)\n<\/pre>\n<p>Now the amqsput program is ready to run with no further intervention<\/p>\n<pre>$ node amqsput\nSample AMQSPUT.JS start\nMQCONN to QM1 successful\nMQOPEN of SYSTEM.DEFAULT.LOCAL.QUEUE successful\nMQPUT successful\nMQCLOSE successful\nMQDISC successful\n<\/pre>\n<h2>Disabling the automatic installation<\/h2>\n<p>It is possible to disable the automatic download of the MQ C runtime. You may have a preferred version of the MQ client libraries, or you may already have installed the client for other reasons and want to reuse the same installation.<\/p>\n<p>Set the environment variable MQIJS_NOREDIST to any value and the file is not downloaded:<\/p>\n<pre>$ export MQIJS_NOREDIST=true\n$ npm install\n... (various messages showing installation of other pieces) ...\n&gt; ibmmq@0.7.0 postinstall \/tmp\/nodetest\/node_modules\/ibmmq\n&gt; node postinstall.js\n\n<strong>Environment variable set to not install IBM MQ Redistributable C Client<\/strong>\namqsput@0.0.1 \/tmp\/nodetest\n\u2514\u2500\u2500 ibmmq@0.7.0\n<\/pre>\n<h3>Platform support<\/h3>\n<p>The redistributable clients are only available for Linux x64 and Windows. The automatic installation attempt is bypassed if you are running on a platform that does not have the Redistributable Client available. In those circumstances, you will have to get the libraries from a more traditional route. And of course, there are platforms where Node.js runs but there is no MQ client available at all. For that situation, you will have to find a completely different mechanism such as running in a VM or container.<\/p>\n<h3>What parts are kept<\/h3>\n<p>The full Redistributable Client packages contain much more than the libraries needed to run a C program. Most of the rest of that package gets deleted by the unpacking process, but one program is left alone \u2013 <strong>runmqsc<\/strong>. That is done so that it is possible to use this downloaded image to create Client Channel Definition Tables (CCDT) from just within the Node directory by using runmqsc with the -n flag. And that in turn is done because you may want to use this solution within a container for simpler deployment. Which is the subject of the next section.<\/p>\n<h2>Docker container<\/h2>\n<p>Included with the ibmmq package is an example for how to build a Docker container that runs an MQ Node.js program.<\/p>\n<p>The Dockerfile shows one way to build from a base image, and add a program along with its prereqs. A script runs the build and then executes the program. The script sets some environment variables including MQSERVER to point at a queue manager.<\/p>\n<p>Unsurprisingly in this case, the program did not have credentials for a successful client connection. But it demonstrates the principle is correct after getting as far as making the initial connection to the remote queue manager.<\/p>\n<pre>$ cd node_modules\/ibmmq\/samples\n$ .\/run.docker\nSending build context to Docker daemon  87.04kB\nStep 1\/13 : FROM debian:jessie-slim\n---&gt; f1ff1c889d54\nStep 2\/13 : ENV NODE_USER app\n...\nStep 13\/13 : CMD node amqsput ${DOCKER_Q} ${DOCKER_QMGR}\n---&gt; Using cache\n---&gt; 0cd6e7086633\nSuccessfully built 0cd6e7086633\nSuccessfully tagged mq-node-demo:latest\nSample AMQSPUT.JS start\nMQ call failed in CONNX: MQCC = MQCC_FAILED [2] MQRC = MQRC_NOT_AUTHORIZED [2035]\n<\/pre>\n<h2>Client connections<\/h2>\n<p>For simplicity, the sample script for building the image takes the most basic approach for defining the client connection. In the docker run command it sets the MQSERVER environment variable. But I have played with a couple of other mechanisms.<\/p>\n<ul>\n<li>As part of the build process, I run runmqsc on the build machine (because I\u2019ve got a full MQ installation) and use it to create a CCDT. Then a step in a Dockerfile copies that CCDT to the container and at runtime I set the environment variables MQCHLLIB and MQCHLTAB to point at where I\u2019ve copied the CCDT.<\/li>\n<li>For a truly self-contained approach where the Docker build machine does not have MQ installed, I can use the fact that runmqsc will exist in the container to put an MQSC script into the build and have a program execute runmqsc there before executing the real program.Something similar would work for TLS certificate stores. Either create the certificate and the store locally and copy as part of the docker build, or build the image and run a command (the gskit libraries and commands are also left inside the unpacked redistributable directory) to populate a store.<\/li>\n<\/ul>\n<h3>Minimising the image<\/h3>\n<p>The Dockerfile is structured to try to minimise the number of layers in the image, as part of making it as small as possible. It starts with a reasonably small base image, a build of debian called <strong>jessie-slim<\/strong>. Then the build combines many operations (in particular, installation of temporary components and their eventual uninstallation) into a single RUN command. It does mean that the mostly likely variation between two containers \u2013 the program itself \u2013 is established about half-way through the build process.<\/p>\n<p>That might slow down generation of multiple containers that only vary by the program code as all the identical subsequent steps need to exeucte for each container build. You could probably tweak Dockerfiles based on better knowledge of differences between your programs and their prereqs so that one of the final steps installs the real program but you would need to be careful not to miss out on pieces of the dependency chain that <code>npm install<\/code> handles for you.<\/p>\n<h2>Summary<\/h2>\n<p>Making it easier to build and deploy MQ applications is important. I hope the new features described here help with that.<\/p>\n<p class=\"last-modified\" style=\"border:1px solid;padding: 10px;\">This post was last updated on November 24th, 2019 at 02:59 pm<\/p>","protected":false},"excerpt":{"rendered":"<p>In November, I wrote about a new language binding to MQ, making it possible to use Javascript in a Node.JS environment to access the MQ API. I published the first release of that code only through GitHub which required that you clone it locally before you could use it. Once the initial public exposure proved &hellip; <a href=\"https:\/\/marketaylor.synology.me\/?p=513\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Easier use of the Node.js interface for MQ&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":510,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[5],"tags":[66,67,35,62,20,63],"class_list":["post-513","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-mq","tag-containers","tag-docker","tag-ibmmq","tag-javascript","tag-mqseries","tag-nodejs"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Easier use of the Node.js interface for MQ - Mark Taylor&#039;s Blog<\/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:\/\/marketaylor.synology.me\/?p=513\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Easier use of the Node.js interface for MQ - Mark Taylor&#039;s Blog\" \/>\n<meta property=\"og:description\" content=\"In November, I wrote about a new language binding to MQ, making it possible to use Javascript in a Node.JS environment to access the MQ API. I published the first release of that code only through GitHub which required that you clone it locally before you could use it. Once the initial public exposure proved &hellip; Continue reading &quot;Easier use of the Node.js interface for MQ&quot;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/marketaylor.synology.me\/?p=513\" \/>\n<meta property=\"og:site_name\" content=\"Mark Taylor&#039;s Blog\" \/>\n<meta property=\"article:published_time\" content=\"2018-06-04T23:34:29+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-11-24T14:59:11+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/marketaylor.synology.me\/wp-content\/uploads\/Pictures\/2019\/11\/nodejs-logo.png\" \/>\n\t<meta property=\"og:image:width\" content=\"256\" \/>\n\t<meta property=\"og:image:height\" content=\"156\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Mark\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@marketaylor\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Mark\" \/>\n\t<meta name=\"twitter:label2\" content=\"Estimated reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=513#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=513\"},\"author\":{\"name\":\"Mark\",\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/#\\\/schema\\\/person\\\/2d6f4113ff54187023e20c20186bbb3c\"},\"headline\":\"Easier use of the Node.js interface for MQ\",\"datePublished\":\"2018-06-04T23:34:29+00:00\",\"dateModified\":\"2019-11-24T14:59:11+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=513\"},\"wordCount\":1199,\"commentCount\":0,\"image\":{\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=513#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/marketaylor.synology.me\\\/wp-content\\\/uploads\\\/Pictures\\\/2019\\\/11\\\/nodejs-logo.png\",\"keywords\":[\"containers\",\"docker\",\"ibmmq\",\"javascript\",\"mqseries\",\"nodejs\"],\"articleSection\":[\"IBM MQ\"],\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/marketaylor.synology.me\\\/?p=513#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=513\",\"url\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=513\",\"name\":\"Easier use of the Node.js interface for MQ - Mark Taylor&#039;s Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=513#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=513#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/marketaylor.synology.me\\\/wp-content\\\/uploads\\\/Pictures\\\/2019\\\/11\\\/nodejs-logo.png\",\"datePublished\":\"2018-06-04T23:34:29+00:00\",\"dateModified\":\"2019-11-24T14:59:11+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/#\\\/schema\\\/person\\\/2d6f4113ff54187023e20c20186bbb3c\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=513#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/marketaylor.synology.me\\\/?p=513\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=513#primaryimage\",\"url\":\"https:\\\/\\\/marketaylor.synology.me\\\/wp-content\\\/uploads\\\/Pictures\\\/2019\\\/11\\\/nodejs-logo.png\",\"contentUrl\":\"https:\\\/\\\/marketaylor.synology.me\\\/wp-content\\\/uploads\\\/Pictures\\\/2019\\\/11\\\/nodejs-logo.png\",\"width\":256,\"height\":156},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=513#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/marketaylor.synology.me\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Easier use of the Node.js interface for MQ\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/#website\",\"url\":\"https:\\\/\\\/marketaylor.synology.me\\\/\",\"name\":\"Mark Taylor&#039;s Blog\",\"description\":\"Messaging, Music and Moving Around\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/marketaylor.synology.me\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-GB\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/#\\\/schema\\\/person\\\/2d6f4113ff54187023e20c20186bbb3c\",\"name\":\"Mark\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/9a5ae091c43730194cba7cabb5d65c1dc3f48d05caaddec6ff2319a1ce66376f?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/9a5ae091c43730194cba7cabb5d65c1dc3f48d05caaddec6ff2319a1ce66376f?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/9a5ae091c43730194cba7cabb5d65c1dc3f48d05caaddec6ff2319a1ce66376f?s=96&d=mm&r=g\",\"caption\":\"Mark\"},\"sameAs\":[\"https:\\\/\\\/x.com\\\/marketaylor\"],\"url\":\"https:\\\/\\\/marketaylor.synology.me\\\/?author=1\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Easier use of the Node.js interface for MQ - Mark Taylor&#039;s Blog","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:\/\/marketaylor.synology.me\/?p=513","og_locale":"en_GB","og_type":"article","og_title":"Easier use of the Node.js interface for MQ - Mark Taylor&#039;s Blog","og_description":"In November, I wrote about a new language binding to MQ, making it possible to use Javascript in a Node.JS environment to access the MQ API. I published the first release of that code only through GitHub which required that you clone it locally before you could use it. Once the initial public exposure proved &hellip; Continue reading \"Easier use of the Node.js interface for MQ\"","og_url":"https:\/\/marketaylor.synology.me\/?p=513","og_site_name":"Mark Taylor&#039;s Blog","article_published_time":"2018-06-04T23:34:29+00:00","article_modified_time":"2019-11-24T14:59:11+00:00","og_image":[{"width":256,"height":156,"url":"https:\/\/marketaylor.synology.me\/wp-content\/uploads\/Pictures\/2019\/11\/nodejs-logo.png","type":"image\/png"}],"author":"Mark","twitter_card":"summary_large_image","twitter_creator":"@marketaylor","twitter_misc":{"Written by":"Mark","Estimated reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/marketaylor.synology.me\/?p=513#article","isPartOf":{"@id":"https:\/\/marketaylor.synology.me\/?p=513"},"author":{"name":"Mark","@id":"https:\/\/marketaylor.synology.me\/#\/schema\/person\/2d6f4113ff54187023e20c20186bbb3c"},"headline":"Easier use of the Node.js interface for MQ","datePublished":"2018-06-04T23:34:29+00:00","dateModified":"2019-11-24T14:59:11+00:00","mainEntityOfPage":{"@id":"https:\/\/marketaylor.synology.me\/?p=513"},"wordCount":1199,"commentCount":0,"image":{"@id":"https:\/\/marketaylor.synology.me\/?p=513#primaryimage"},"thumbnailUrl":"https:\/\/marketaylor.synology.me\/wp-content\/uploads\/Pictures\/2019\/11\/nodejs-logo.png","keywords":["containers","docker","ibmmq","javascript","mqseries","nodejs"],"articleSection":["IBM MQ"],"inLanguage":"en-GB","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/marketaylor.synology.me\/?p=513#respond"]}]},{"@type":"WebPage","@id":"https:\/\/marketaylor.synology.me\/?p=513","url":"https:\/\/marketaylor.synology.me\/?p=513","name":"Easier use of the Node.js interface for MQ - Mark Taylor&#039;s Blog","isPartOf":{"@id":"https:\/\/marketaylor.synology.me\/#website"},"primaryImageOfPage":{"@id":"https:\/\/marketaylor.synology.me\/?p=513#primaryimage"},"image":{"@id":"https:\/\/marketaylor.synology.me\/?p=513#primaryimage"},"thumbnailUrl":"https:\/\/marketaylor.synology.me\/wp-content\/uploads\/Pictures\/2019\/11\/nodejs-logo.png","datePublished":"2018-06-04T23:34:29+00:00","dateModified":"2019-11-24T14:59:11+00:00","author":{"@id":"https:\/\/marketaylor.synology.me\/#\/schema\/person\/2d6f4113ff54187023e20c20186bbb3c"},"breadcrumb":{"@id":"https:\/\/marketaylor.synology.me\/?p=513#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/marketaylor.synology.me\/?p=513"]}]},{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/marketaylor.synology.me\/?p=513#primaryimage","url":"https:\/\/marketaylor.synology.me\/wp-content\/uploads\/Pictures\/2019\/11\/nodejs-logo.png","contentUrl":"https:\/\/marketaylor.synology.me\/wp-content\/uploads\/Pictures\/2019\/11\/nodejs-logo.png","width":256,"height":156},{"@type":"BreadcrumbList","@id":"https:\/\/marketaylor.synology.me\/?p=513#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/marketaylor.synology.me\/"},{"@type":"ListItem","position":2,"name":"Easier use of the Node.js interface for MQ"}]},{"@type":"WebSite","@id":"https:\/\/marketaylor.synology.me\/#website","url":"https:\/\/marketaylor.synology.me\/","name":"Mark Taylor&#039;s Blog","description":"Messaging, Music and Moving Around","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/marketaylor.synology.me\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-GB"},{"@type":"Person","@id":"https:\/\/marketaylor.synology.me\/#\/schema\/person\/2d6f4113ff54187023e20c20186bbb3c","name":"Mark","image":{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/secure.gravatar.com\/avatar\/9a5ae091c43730194cba7cabb5d65c1dc3f48d05caaddec6ff2319a1ce66376f?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/9a5ae091c43730194cba7cabb5d65c1dc3f48d05caaddec6ff2319a1ce66376f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/9a5ae091c43730194cba7cabb5d65c1dc3f48d05caaddec6ff2319a1ce66376f?s=96&d=mm&r=g","caption":"Mark"},"sameAs":["https:\/\/x.com\/marketaylor"],"url":"https:\/\/marketaylor.synology.me\/?author=1"}]}},"jetpack_featured_media_url":"https:\/\/marketaylor.synology.me\/wp-content\/uploads\/Pictures\/2019\/11\/nodejs-logo.png","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/marketaylor.synology.me\/index.php?rest_route=\/wp\/v2\/posts\/513","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/marketaylor.synology.me\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/marketaylor.synology.me\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/marketaylor.synology.me\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/marketaylor.synology.me\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=513"}],"version-history":[{"count":4,"href":"https:\/\/marketaylor.synology.me\/index.php?rest_route=\/wp\/v2\/posts\/513\/revisions"}],"predecessor-version":[{"id":526,"href":"https:\/\/marketaylor.synology.me\/index.php?rest_route=\/wp\/v2\/posts\/513\/revisions\/526"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/marketaylor.synology.me\/index.php?rest_route=\/wp\/v2\/media\/510"}],"wp:attachment":[{"href":"https:\/\/marketaylor.synology.me\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=513"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/marketaylor.synology.me\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=513"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/marketaylor.synology.me\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=513"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}