{"id":1112,"date":"2022-01-14T10:02:43","date_gmt":"2022-01-14T10:02:43","guid":{"rendered":"https:\/\/marketaylor.synology.me\/?p=1112"},"modified":"2022-01-26T13:53:43","modified_gmt":"2022-01-26T13:53:43","slug":"mq-nodejs-typescript","status":"publish","type":"post","link":"https:\/\/marketaylor.synology.me\/?p=1112","title":{"rendered":"MQ and Node.js: working with TypeScript"},"content":{"rendered":"\n<p>MQ application programs for the Node.js environment can now use TypeScript definitions. This brings the opportunity to compile and check your JavaScript programs for correctness before running them. This post will talk more about what TypeScript is and how it can help your MQ Node.js development activity.<\/p>\n\n\n\n<p>Substantial credit for the API definitions and translations of the example programs needs to be given to <a href=\"https:\/\/github.com\/asselin\" target=\"_blank\" rel=\"noreferrer noopener\">Andre<\/a>, who submitted a <a href=\"https:\/\/github.com\/ibm-messaging\/mq-mqi-nodejs\/pull\/134\" target=\"_blank\" rel=\"noreferrer noopener\">Pull Request<\/a> to our github repository.<\/p>\n\n\n\n<!--more-->\n\n\n\n<h3 class=\"wp-block-heading\">The MQ Node.js bindings<\/h3>\n\n\n\n<p>In <a href=\"https:\/\/marketaylor.synology.me\/?p=505\" target=\"_blank\" rel=\"noreferrer noopener\">this article<\/a>, I wrote about a set of bindings that allow you to write JavaScript programs for Node.js with access to full MQ capabilities. The interface provides a version of the MQI mapped into a style that is more natural for JavaScript programmers. And the package is designed to be easy to install and work with. It automatically pulls in the MQ client runtime prerequisite where it can be done, reducing effort during deployment. The full code library is on <a href=\"https:\/\/github.com\/ibm-messaging\/mq-mqi-nodejs\" target=\"_blank\" rel=\"noreferrer noopener\">github<\/a>, but much of the time people will simply allow <code>npm install<\/code> to obtain the pieces they need. The package has evolved, with new features added as the base MQ product gets enhanced. There have also been additional sample programs and scripts to show different ways of using it.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">What is TypeScript<\/h3>\n\n\n\n<p><a href=\"https:\/\/nodejs.dev\/learn\/nodejs-with-typescript\/\" target=\"_blank\" rel=\"noreferrer noopener\">TypeScript<\/a> is an extension to the JavaScript language. It is essentially a superset, where objects have known types (number, string, named structure etc) instead of having no specific type. Function definitions state which type is used for each parameter. The types are then checked at compile time instead of causing runtime failures. You cannot assign a value to a variable if it is the wrong type. This makes programs more secure and robust as many problems in application code can be caught early in the process instead of showing up when the program is already in production. <\/p>\n\n\n\n<p>This is the kind of behaviour I have always expected to see in serious programming languages, but it is not part of JavaScript. Untyped languages can be fine for scripts and very simple short programs, but use of JavaScript has ballooned. Programs are much longer than the original, simple, intention of the language to give a level of dynamic content in web pages. It is also harder for a programming team working on a product to keep track of what kinds of objects should be passed around between different pieces of the program: source code comments are never sufficient.<\/p>\n\n\n\n<p>A TypeScript program is compiled into JavaScript, with errors being detected at that point. The generated JavaScript can then be executed directly. Because of this process, you can easily mix TypeScript code with &#8220;traditional&#8221; JavaScript code &#8211; there is no enforcement of using object types in application code. Though programs like <code>eslint<\/code> can be used to check your style.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">The MQ TypeScript enhancements<\/h3>\n\n\n\n<p>Because you can mix JavaScript with TypeScript, there is no absolute requirement for any API to give a declaration of its interface. Clearly, however, it can make things better for the application programmer. So what we now have with the MQI bindings are declarations for all of the application-callable functions and the associated structures. <\/p>\n\n\n\n<p>For example,  this is the declaration of the <code>Open<\/code> function (the spelling of <code>MQOPEN<\/code> in this binding). <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">function Open(\n     jsQueueManager: MQQueueManager,\n     jsod: MQOD,\n     jsOpenOptions: number,\n     cb: (err: MQError | null, obj: MQObject) =&gt; void\n   ): void;<\/pre>\n\n\n\n<p>We can see all of the input parameters with their associated types &#8211; there are corresponding definitions of the <code>MQQueueManager<\/code> and the <code>MQOD<\/code> classes &#8211; and what kinds of parameters get sent to the asynchronous callback function invoked when the <code>Open<\/code> completes. The TypeScript syntax can assert several different types that a parameter might be. For example, the first parameter to the callback will either be an <code>MQError<\/code> object, or null.<\/p>\n\n\n\n<p>Many of the fields in structures can only hold certain values from the complete set of MQI definitions. Where possible, those subsets have been named in <code>enum<\/code> ranges to give an additional level of checking.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Running programs<\/h3>\n\n\n\n<p>There are several sample programs, converted from the original JavaScript versions, in the <em>samples\/typescript<\/em> directory of the repository. To run one of them, copy it to a suitable place and then add a <em>package.json<\/em> file:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">{\n   \"name\": \"amqsput\",\n   \"description\": \"Example of TypeScript program\",\n   \"main\": \"amqsput.ts\",\n   \"dependencies\": {\n     \"ibmmq\": \"&gt;=0.9.20\"\n   },\n   \"devDependencies\": {\n     \"@types\/node\": \"^16.11.19\",\n     \"typescript\": \"^4.5.4\"\n   }\n }<\/pre>\n\n\n\n<p>Version <code>0.9.20<\/code> is the first version of the package to include these definitions. But the type information is not needed for running the programs, after compiling into JavaScript. The <code>devDependencies<\/code> block in here allows us to separate what is needed at runtime from what is needed at build time. You can use <code>npm install --only=prod<\/code> to create runtime-only environments.<\/p>\n\n\n\n<p>Note: Version <code>0.9.21<\/code> includes <em>package.json.sample<\/em> which can be used as the skeleton for your own <em>package.json<\/em> so you don&#8217;t have to create one from scratch.<\/p>\n\n\n\n<p>Assuming you have a TypeScript compiler installed (<code>npm install -g typescript<\/code> if you don&#8217;t), you can then <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ npm install\nvarious messages ...\n$ tsc amqsput.ts  \/\/ This compiles the code into JavaScript\n$ node amqsput.js \/\/ And now run the real program<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Finding errors<\/h4>\n\n\n\n<p>The important difference between TypeScript and JavaScript shows up when there is an error in your program. Here is one example of a deliberate mistake. I have swapped two parameters to the <code>Put<\/code> function. This is the kind of error I regularly make as I can never remember exactly which order everything goes in. So given the <em><a href=\"https:\/\/github.com\/ibm-messaging\/mq-mqi-nodejs\/blob\/master\/samples\/typescript\/amqsput.ts\" target=\"_blank\" rel=\"noreferrer noopener\">amqsput.ts<\/a><\/em> or <em><a href=\"https:\/\/github.com\/ibm-messaging\/mq-mqi-nodejs\/blob\/master\/samples\/amqsput.js\" target=\"_blank\" rel=\"noreferrer noopener\">amqsput.js<\/a><\/em> samples in the repository, the correct line is<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">mq.Put(hObj, mqmd, pmo, msg, function (err) {<\/pre>\n\n\n\n<p>I changed that to<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">mq.Put(hObj, pmo, mqmd, msg, function (err) {<\/pre>\n\n\n\n<p>and tried to build or run the programs. In the JavaScript case, I am in the middle of running the program before receiving an error. And it&#8217;s not a particularly helpful error message. You can imagine how horrible it would be if this runtime error showed up only in a rarely-executed path of your program.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ node amqsput.js\nSample AMQSPUT.JS start\nMQCONN to QM1 successful \nMQOPEN of DEV.QUEUE.1 successful\nterminate called after throwing an instance of 'Napi::Error'\n  what():  Parameter must be of type MQMD\nAborted (core dumped)<\/pre>\n\n\n\n<p>Contrast that with the error that comes out when compiling the TypeScript program. We get a useful error message, and even the rare paths will have been checked as we are not running the program.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ tsc amqsput.ts\namqsput.ts:69:16 - error TS2345: Argument of type 'MQPMO' is not assignable to parameter of type 'MQMD'.\n   Type 'MQPMO' is missing the following properties from type 'MQMD': Report, MsgType, Expiry, Feedback, and 23 more.\n 69   mq.Put(hObj, pmo, mqmd, msg, function (err) {<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Health Warning<\/h3>\n\n\n\n<p>This initial release of the TypeScript definitions is subject to change based on feedback. I can already see a couple of enhancements I&#8217;d like to make. But getting the code released not just in the github repository but also in the npm installation ecosystem gives the opportunity for people to try it and give comments about the details and value.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Update History<\/h3>\n\n\n\n<ul class=\"wp-block-list\"><li>2022-01-14: Initial release<\/li><li>2022-01-26: Version 0.9.21 includes a starting point for the <em>package.json<\/em> file.<\/li><\/ul>\n<p class=\"last-modified\" style=\"border:1px solid;padding: 10px;\">This post was last updated on January 26th, 2022 at 01:53 pm<\/p>","protected":false},"excerpt":{"rendered":"<p>MQ application programs for the Node.js environment can now use TypeScript definitions. This brings the opportunity to compile and check your JavaScript programs for correctness before running them. This post will talk more about what TypeScript is and how it can help your MQ Node.js development activity. Substantial credit for the API definitions and translations &hellip; <a href=\"https:\/\/marketaylor.synology.me\/?p=1112\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;MQ and Node.js: working with TypeScript&#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":[35,62,20,63,116],"class_list":["post-1112","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-mq","tag-ibmmq","tag-javascript","tag-mqseries","tag-nodejs","tag-typescript"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>MQ and Node.js: working with TypeScript - Mark Taylor&#039;s Blog<\/title>\n<meta name=\"description\" content=\"MQ and Node.js now work with TypeScript. These definitions give improved checking of your application program code.\" \/>\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=1112\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"MQ and Node.js: working with TypeScript - Mark Taylor&#039;s Blog\" \/>\n<meta property=\"og:description\" content=\"MQ and Node.js now work with TypeScript. These definitions give improved checking of your application program code.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/marketaylor.synology.me\/?p=1112\" \/>\n<meta property=\"og:site_name\" content=\"Mark Taylor&#039;s Blog\" \/>\n<meta property=\"article:published_time\" content=\"2022-01-14T10:02:43+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-01-26T13:53:43+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=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=1112#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=1112\"},\"author\":{\"name\":\"Mark\",\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/#\\\/schema\\\/person\\\/2d6f4113ff54187023e20c20186bbb3c\"},\"headline\":\"MQ and Node.js: working with TypeScript\",\"datePublished\":\"2022-01-14T10:02:43+00:00\",\"dateModified\":\"2022-01-26T13:53:43+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=1112\"},\"wordCount\":1030,\"commentCount\":0,\"image\":{\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=1112#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/marketaylor.synology.me\\\/wp-content\\\/uploads\\\/Pictures\\\/2019\\\/11\\\/nodejs-logo.png\",\"keywords\":[\"ibmmq\",\"javascript\",\"mqseries\",\"nodejs\",\"typescript\"],\"articleSection\":[\"IBM MQ\"],\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/marketaylor.synology.me\\\/?p=1112#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=1112\",\"url\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=1112\",\"name\":\"MQ and Node.js: working with TypeScript - Mark Taylor&#039;s Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=1112#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=1112#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/marketaylor.synology.me\\\/wp-content\\\/uploads\\\/Pictures\\\/2019\\\/11\\\/nodejs-logo.png\",\"datePublished\":\"2022-01-14T10:02:43+00:00\",\"dateModified\":\"2022-01-26T13:53:43+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/#\\\/schema\\\/person\\\/2d6f4113ff54187023e20c20186bbb3c\"},\"description\":\"MQ and Node.js now work with TypeScript. These definitions give improved checking of your application program code.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=1112#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/marketaylor.synology.me\\\/?p=1112\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\\\/\\\/marketaylor.synology.me\\\/?p=1112#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=1112#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/marketaylor.synology.me\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"MQ and Node.js: working with TypeScript\"}]},{\"@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":"MQ and Node.js: working with TypeScript - Mark Taylor&#039;s Blog","description":"MQ and Node.js now work with TypeScript. These definitions give improved checking of your application program code.","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=1112","og_locale":"en_GB","og_type":"article","og_title":"MQ and Node.js: working with TypeScript - Mark Taylor&#039;s Blog","og_description":"MQ and Node.js now work with TypeScript. These definitions give improved checking of your application program code.","og_url":"https:\/\/marketaylor.synology.me\/?p=1112","og_site_name":"Mark Taylor&#039;s Blog","article_published_time":"2022-01-14T10:02:43+00:00","article_modified_time":"2022-01-26T13:53:43+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":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/marketaylor.synology.me\/?p=1112#article","isPartOf":{"@id":"https:\/\/marketaylor.synology.me\/?p=1112"},"author":{"name":"Mark","@id":"https:\/\/marketaylor.synology.me\/#\/schema\/person\/2d6f4113ff54187023e20c20186bbb3c"},"headline":"MQ and Node.js: working with TypeScript","datePublished":"2022-01-14T10:02:43+00:00","dateModified":"2022-01-26T13:53:43+00:00","mainEntityOfPage":{"@id":"https:\/\/marketaylor.synology.me\/?p=1112"},"wordCount":1030,"commentCount":0,"image":{"@id":"https:\/\/marketaylor.synology.me\/?p=1112#primaryimage"},"thumbnailUrl":"https:\/\/marketaylor.synology.me\/wp-content\/uploads\/Pictures\/2019\/11\/nodejs-logo.png","keywords":["ibmmq","javascript","mqseries","nodejs","typescript"],"articleSection":["IBM MQ"],"inLanguage":"en-GB","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/marketaylor.synology.me\/?p=1112#respond"]}]},{"@type":"WebPage","@id":"https:\/\/marketaylor.synology.me\/?p=1112","url":"https:\/\/marketaylor.synology.me\/?p=1112","name":"MQ and Node.js: working with TypeScript - Mark Taylor&#039;s Blog","isPartOf":{"@id":"https:\/\/marketaylor.synology.me\/#website"},"primaryImageOfPage":{"@id":"https:\/\/marketaylor.synology.me\/?p=1112#primaryimage"},"image":{"@id":"https:\/\/marketaylor.synology.me\/?p=1112#primaryimage"},"thumbnailUrl":"https:\/\/marketaylor.synology.me\/wp-content\/uploads\/Pictures\/2019\/11\/nodejs-logo.png","datePublished":"2022-01-14T10:02:43+00:00","dateModified":"2022-01-26T13:53:43+00:00","author":{"@id":"https:\/\/marketaylor.synology.me\/#\/schema\/person\/2d6f4113ff54187023e20c20186bbb3c"},"description":"MQ and Node.js now work with TypeScript. These definitions give improved checking of your application program code.","breadcrumb":{"@id":"https:\/\/marketaylor.synology.me\/?p=1112#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/marketaylor.synology.me\/?p=1112"]}]},{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/marketaylor.synology.me\/?p=1112#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=1112#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/marketaylor.synology.me\/"},{"@type":"ListItem","position":2,"name":"MQ and Node.js: working with TypeScript"}]},{"@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\/1112","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=1112"}],"version-history":[{"count":8,"href":"https:\/\/marketaylor.synology.me\/index.php?rest_route=\/wp\/v2\/posts\/1112\/revisions"}],"predecessor-version":[{"id":1125,"href":"https:\/\/marketaylor.synology.me\/index.php?rest_route=\/wp\/v2\/posts\/1112\/revisions\/1125"}],"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=1112"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/marketaylor.synology.me\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1112"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/marketaylor.synology.me\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1112"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}