{"id":312,"date":"2023-08-04T09:50:45","date_gmt":"2023-08-04T08:50:45","guid":{"rendered":"https:\/\/www.bolukan.nl\/?p=312"},"modified":"2023-08-04T16:51:12","modified_gmt":"2023-08-04T15:51:12","slug":"combine-influxdb-data-and-mysql-metadata-in-grafana","status":"publish","type":"post","link":"https:\/\/www.bolukan.nl\/?p=312","title":{"rendered":"Combine Influxdb data and mysql metadata in Grafana"},"content":{"rendered":"\n<h3 class=\"wp-block-heading\">Addition of metadata is not supported well in Grafana<\/h3>\n\n\n\n<p>InfluxDB enables efficient time-series data storage and retrieval and Grafana is a platform to create and share interactive, customizable dashboards. Tags, the metadata for sorting and grouping, are often not human readable and need enrichment. A simple example is a deviceid of a sensor which is stored in the database but you want to present the location or it&#8217;s nickname.<\/p>\n\n\n\n<p>The standard solution is to centrally maintain a table with the extra metadata that is combined in the query and adds the needed datapoints to present in the dashboard. However InfluxDB is not like a traditional SQL database and finding no solutions on the internet it seemed too hard to realise.<\/p>\n\n\n\n<p>The solution advised by Grafana and in forums is to add Transformations in Grafana to manipulate and enrich the metadata. These transformations need to be added to each dashboard and need to be repeated for each textstring that you want to add. It requires a lot of maintenance, leading to a higher chance of introducing errors and inconsistencies.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">How to add metadata from another database and enrich your dashboard<\/h3>\n\n\n\n<p>However, I succeeded to combine InfluxDB data with metadata from a MYSQL database. Let&#8217;s first give you the example and explain the important parts so you can adjust it to your situation. In Grafana select as Data source &#8220;Influx-DB-Flux&#8221; and paste the code:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#d8dee9ff;--cbp-line-number-width:17.60003662109375px;line-height:1.25rem\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"import &quot;sql&quot;\nimport &quot;join&quot;\n\nusername = &quot;imayreadsql&quot;\npassword = &quot;donttellanybody&quot;\nmysql_server = &quot;192.168.1.2:3306&quot;\n\ndevices = sql.from(\n  driverName: &quot;mysql&quot;,\n  dataSourceName: &quot;${username}:${password}@tcp(${mysql_server})\/sensor&quot;,\n  query: &quot;SELECT * FROM grafana&quot;,\n)\n\ndata = from(bucket: &quot;mytimeseries&quot;)\n  |&gt; range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |&gt; filter(fn: (r) =&gt; r[&quot;_measurement&quot;] == &quot;Temperature&quot;)\n  |&gt; filter(fn: (r) =&gt; r[&quot;_field&quot;] == &quot;temperature&quot;)\n  |&gt; aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n  |&gt; group()\n\njoin.inner(\n  left: data,\n  right: devices,\n  on: (l, r) =&gt; l.topic == r.topic,\n  as: (l, r) =&gt; ({l with location: r.location}),\n)\n  |&gt; group(columns: [&quot;_time&quot;, &quot;_value&quot;], mode: &quot;except&quot;)\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D8DEE9FF\">import <\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">sql<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">import <\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">join<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">username <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">imayreadsql<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">password<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">donttellanybody<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">mysql_server <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">192.168.1.2:3306<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">devices <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> sql.from(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">  driverName: <\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">mysql<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #D8DEE9FF\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">  dataSourceName: <\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">${username}:${password}@tcp(${mysql_server})\/sensor<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #D8DEE9FF\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">  query: <\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">SELECT * FROM grafana<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #D8DEE9FF\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">data<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">from<\/span><span style=\"color: #D8DEE9FF\">(bucket: <\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">mytimeseries<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">  |<\/span><span style=\"color: #81A1C1\">&gt;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">range<\/span><span style=\"color: #D8DEE9FF\">(<\/span><span style=\"color: #81A1C1\">start<\/span><span style=\"color: #D8DEE9FF\">: v.timeRangeStart, <\/span><span style=\"color: #81A1C1\">stop<\/span><span style=\"color: #D8DEE9FF\">: v.timeRangeStop)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">  |<\/span><span style=\"color: #81A1C1\">&gt;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">filter<\/span><span style=\"color: #D8DEE9FF\">(fn: (r) <\/span><span style=\"color: #81A1C1\">=&gt;<\/span><span style=\"color: #D8DEE9FF\"> r[&quot;_measurement&quot;] <\/span><span style=\"color: #81A1C1\">==<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">Temperature<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">  |<\/span><span style=\"color: #81A1C1\">&gt;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">filter<\/span><span style=\"color: #D8DEE9FF\">(fn: (r) <\/span><span style=\"color: #81A1C1\">=&gt;<\/span><span style=\"color: #D8DEE9FF\"> r[&quot;_field&quot;] <\/span><span style=\"color: #81A1C1\">==<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">temperature<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">  |<\/span><span style=\"color: #81A1C1\">&gt;<\/span><span style=\"color: #D8DEE9FF\"> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">  |<\/span><span style=\"color: #81A1C1\">&gt;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">group<\/span><span style=\"color: #D8DEE9FF\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">join<\/span><span style=\"color: #D8DEE9FF\">.inner(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">  left: <\/span><span style=\"color: #81A1C1\">data<\/span><span style=\"color: #D8DEE9FF\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">  right: devices,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">  <\/span><span style=\"color: #81A1C1\">on<\/span><span style=\"color: #D8DEE9FF\">: (l, r) <\/span><span style=\"color: #81A1C1\">=&gt;<\/span><span style=\"color: #D8DEE9FF\"> l.topic <\/span><span style=\"color: #81A1C1\">==<\/span><span style=\"color: #D8DEE9FF\"> r.topic,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">  <\/span><span style=\"color: #81A1C1\">as<\/span><span style=\"color: #D8DEE9FF\">: (l, r) <\/span><span style=\"color: #81A1C1\">=&gt;<\/span><span style=\"color: #D8DEE9FF\"> ({l <\/span><span style=\"color: #81A1C1\">with<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">location<\/span><span style=\"color: #D8DEE9FF\">: r.location}),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">  |<\/span><span style=\"color: #81A1C1\">&gt;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">group<\/span><span style=\"color: #D8DEE9FF\">(columns: [&quot;_time&quot;, &quot;_value&quot;], mode: <\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">except<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Inside the &#8220;rabbit hole&#8221;<\/h3>\n\n\n\n<p>The <strong>libraries <\/strong>are needed to include a sql source and join tables. <\/p>\n\n\n\n<p>The table &#8220;grafana&#8221; (line 11) in the mysql database &#8220;sensor&#8221; (line 10) contain a column &#8220;topic&#8221; (line 24 &#8216;r.topic&#8217;) and &#8220;location&#8221;. Change these lines with the <strong>SQL-query<\/strong> to suite your situation.<\/p>\n\n\n\n<p>Now get your own <strong>Flux statement<\/strong>, put &#8220;<code>data =<\/code>&#8221; in front and replace the last line &#8211; containing <code>|&gt; yield(name=\"xxxx\")<\/code> &#8211; with the <code>|&gt; group()<\/code> command as shown in line 19. This ungroups the data, which will be regrouped after the merge with the metadata.<\/p>\n\n\n\n<p>The <strong>join.inner<\/strong> statement combines the data on the Tag topic <code>l.topic<\/code> &#8211; which existance was invisible for you in lines 14-19 but now you know &#8211; with the SQL field topic <code>r.topic<\/code> and in the output (line 25) the MYSQL-column <code>location<\/code> is included in the output. <\/p>\n\n\n\n<p>The <code>grafana<\/code> table contains <strong>more metadata<\/strong> then you see now, but I decided to only expose the location, if needed you could add more columns from the table grafana: <code>{location: r.location, description: r.nickname}<\/code>.<\/p>\n\n\n\n<p>Last line is too <strong>regroup<\/strong> the data into the relevant series.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Use of the metadata<\/h3>\n\n\n\n<p>An example to use the metadata is to change the Display name to <code>${__field.labels.location} (${__field.labels.topic})<\/code> which may result in &#8220;Kitchen (AB09)&#8221;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Further improvements<\/h3>\n\n\n\n<p>Removed from the example above, but nice to tell you: I don&#8217;t store and maintain my secrets in the code. Secrets can be stored in many ways and I chose to put the mysql database credentials as <a href=\"https:\/\/docs.influxdata.com\/influxdb\/cloud\/security\/secrets\/add\/\" data-type=\"URL\" data-id=\"https:\/\/docs.influxdata.com\/influxdb\/cloud\/security\/secrets\/add\/\" target=\"_blank\" rel=\"noreferrer noopener\">secret variables into InfluxDB<\/a>. To retrieve them in Grafana simply change the code with these lines:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:1rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#d8dee9ff;--cbp-line-number-width:8.800018310546875px;line-height:1.25rem\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"import &quot;influxdata\/influxdb\/secrets&quot;\n\nusername = secrets.get(key: &quot;MYSQL_USERNAME&quot;)\npassword = secrets.get(key: &quot;MYSQL_PASSWORD&quot;)\nmysql_server = secrets.get(key: &quot;MYSQL_SERVER&quot;)\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D8DEE9FF\">import <\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">influxdata\/influxdb\/secrets<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">username <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> secrets.get(<\/span><span style=\"color: #81A1C1\">key<\/span><span style=\"color: #D8DEE9FF\">: <\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">MYSQL_USERNAME<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #81A1C1\">password<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> secrets.get(<\/span><span style=\"color: #81A1C1\">key<\/span><span style=\"color: #D8DEE9FF\">: <\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">MYSQL_PASSWORD<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">mysql_server <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> secrets.get(<\/span><span style=\"color: #81A1C1\">key<\/span><span style=\"color: #D8DEE9FF\">: <\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #A3BE8C\">MYSQL_SERVER<\/span><span style=\"color: #ECEFF4\">&quot;<\/span><span style=\"color: #D8DEE9FF\">)<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p><br><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The solution described allows for enriching metadata in Grafana by combining data from InfluxDB with data from a MySQL database. This is achieved using Flux, the query language for InfluxDB, and the join function to merge the data based on a common attribute (topic in this case).<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[26,21,27],"class_list":["post-312","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-grafana","tag-influxdb","tag-mysql"],"_links":{"self":[{"href":"https:\/\/www.bolukan.nl\/index.php?rest_route=\/wp\/v2\/posts\/312","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.bolukan.nl\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.bolukan.nl\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.bolukan.nl\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.bolukan.nl\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=312"}],"version-history":[{"count":19,"href":"https:\/\/www.bolukan.nl\/index.php?rest_route=\/wp\/v2\/posts\/312\/revisions"}],"predecessor-version":[{"id":338,"href":"https:\/\/www.bolukan.nl\/index.php?rest_route=\/wp\/v2\/posts\/312\/revisions\/338"}],"wp:attachment":[{"href":"https:\/\/www.bolukan.nl\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=312"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.bolukan.nl\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=312"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.bolukan.nl\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=312"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}