{"id":226,"date":"2021-03-12T20:57:55","date_gmt":"2021-03-12T20:57:55","guid":{"rendered":"https:\/\/andrejacobs.org\/?p=226"},"modified":"2022-04-11T20:24:23","modified_gmt":"2022-04-11T20:24:23","slug":"100-days-of-learning-day-4-using-environment-variables-and-secrets-in-openfaas","status":"publish","type":"post","link":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-4-using-environment-variables-and-secrets-in-openfaas\/","title":{"rendered":"100 Days of Learning: Day 4 \u2013 Using Environment variables and Secrets in OpenFaaS"},"content":{"rendered":"\n

Photo by Zbynek Burival<\/a> on Unsplash<\/a><\/p>\n\n\n\n

Here is my Log book<\/a><\/p>\n

Today I managed to learn more about OpenFaaS as well as refresh some Swift knowledge.<\/p>\n

OpenFaaS<\/h2>\n

Learning action point:<\/strong> Is it possible to bundle up functions to be in the same docker container image? At the moment it looks like 1 function = 1 docker image<\/p>\n

Supplying configuration values via environment variables<\/h3>\n

In Serverless for Everyone Else<\/a>, Alex gives us an example of how environment variables can be supplied to the node.js function via the YAML file.<\/p>\n

I am going to see if I can modify my Python function from yesterday to be configurable in the same way.<\/p>\n

Added the section environment<\/code> to my "helloworld.yml" file to configure how the JSON will be prettified.<\/p>\n

version: 1.0\nprovider:\n  name: openfaas\n  gateway: http:\/\/192.168.64.4:8080\nfunctions:\n  helloworld:\n    lang: python3\n    handler: .\/helloworld\n    image: dockername\/helloworld:latest\n\n    environment:\n        indent: 2\n        sort_keys: false\n<\/code><\/pre>\n

Changed the "handler.py" to read the values for the indentation level and whether to sort the JSON keys from the environment variables. The default indentation level is 4 spaces and to not sort the keys.<\/p>\n

import json\nimport os\n\ndef handle(req):\n    indent = int(os.environ.get('indent', '4'))\n    sort_keys = os.environ.get('sort_keys', 'false').lower() in ['true', 'yes', '1']\n    data = json.loads(req)\n    response = json.dumps(data, indent=indent, sort_keys=sort_keys)\n    return response\n<\/code><\/pre>\n

Deploy<\/p>\n

$ faas-cli up -f helloworld.yml\n...\n<Had a few issues because the YAML contained TABS in the wrong places>\n...\nDeployed. 200 OK.\nURL: http:\/\/192.168.64.4:8080\/function\/helloworld.openfaas-fn\n\n<\/code><\/pre>\n

Test<\/p>\n

$ curl --data-binary '{"z": 1, "a": 2, "c": 3, "b": 4}' --header "Content-Type: application\/json" http:\/\/192.168.64.4:8080\/function\/helloworld\n{\n  "z": 1,\n  "a": 2,\n  "c": 3,\n  "b": 4\n}\n<\/code><\/pre>\n

So what is the benefit in using environment variables? It allows you to not hardcode values all over the place in your code. Also I noticed that creating the docker image is quicker when only the yaml has changed.<\/p>\n

NOTE:<\/strong> Do not use environment variables to store secret information! See the official OpenFaaS documentation<\/a> for more information. Also there is a really nice example in Serverless for Everyone Else<\/a> that shows how to protect your API using a secret token.<\/p>\n

Supplying secret values to your function<\/h3>\n

To explore this I am going to deploy a new function that will read a stored secret and return it back to the caller.<\/p>\n

Note:<\/strong><\/p>\n

Secret name must start and end with an alphanumeric character\nand can only contain lower-case alphanumeric characters, ‘-‘ or ‘.’<\/p>\n

# Remember to first mkdir the directory for the function!\n\u256d ~\/Learning\/faasd\/expose                                                                [20:05:44]\n\u2570 $ faas-cli new --lang python3 expose\n<\/code><\/pre>\n

Add the names of secrets you want access to the yaml file<\/p>\n

version: 1.0\nprovider:\n  name: openfaas\n  gateway: http:\/\/192.168.64.4:8080\nfunctions:\n  expose:\n    lang: python3\n    handler: .\/expose\n    image: dockername\/expose:latest\n\n    secrets:\n      - expose-me\n<\/code><\/pre>\n

I have added a secret with the name "expose-me" and thus our function will have access to it by the file "\/var\/openfaas\/secrets\/expose-me"<\/p>\n

Edit the handler.py file<\/p>\n

def handle(req):\n    with open('\/var\/openfaas\/secrets\/expose-me') as f:\n        secret = f.read()\n    return secret\n<\/code><\/pre>\n

Deploy<\/p>\n

$ faas-cli up -f expose.yml\n...\nUnexpected status: 400, message: unable to find secret: expose-me\n<\/code><\/pre>\n

Right ok, need to first actually add the secret to be used<\/p>\n

$ faas-cli secret create expose-me --from-literal 'All your secrets have been exposed'\n...\nCreating secret: expose-me\nCreated: 200 OK\n\n$ faas-cli secret list\nNAME\nexpose-me\n<\/code><\/pre>\n

Deploy mk2<\/p>\n

$ faas-cli up -f expose.yml\n...\nDeployed. 200 OK.\nURL: http:\/\/192.168.64.4:8080\/function\/expose.openfaas-fn\n<\/code><\/pre>\n

Test<\/p>\n

$ curl http:\/\/192.168.64.4:8080\/function\/expose\nAll your secrets have been exposed\n<\/code><\/pre>\n

Ouch! our secret was exposed. Let us see if we can change the secret.<\/p>\n

$ faas-cli secret help\n...\nAvailable Commands:\n  create      Create a new secret\n  list        List all secrets\n  remove      remove a secret\n  update      Update a secret\n\n$ faas-cli secret update expose-me --from-literal 'Honeypot'\nUpdating secret: expose-me\nUpdated: 200 OK\n\n$ curl http:\/\/192.168.64.4:8080\/function\/expose\nHoneypot\n<\/code><\/pre>\n

Nuke the exposed secret and hopefully the Python code will blow up.<\/p>\n

$ faas-cli secret remove expose-me\nRemoved.. OK.\n\n$ curl http:\/\/192.168.64.4:8080\/function\/expose\nHoneypot\n# Ouch! ok I wasn't expecting that. My guess is the \/var\/... file still exists\n<\/code><\/pre>\n

Learning action point:<\/strong> Will need to read the docs and possibly the code to see how the secrets are stored \/ communicated over to the faasd instance and why remove didn’t remove the stored file.<\/p>\n


\n

Swift: Mutating Objects is different than Mutating Structs<\/strong><\/h2>\n

Objects (instances of a Class) are reference types.<\/p>\n

Structs are value types<\/p>\n

If you have a number of variables pointing to an object and you mutate the object, then each one of the variables will be pointing to the same mutated object. This could become dangerous if the object are being accessed from different threads and leads to the classic concurrency issue of a race condition.<\/p>\n

Structs in Swift allow you to mutate without having the global side effects.<\/p>\n

Mutating a struct only changes a single variable and not all variables with the same value.<\/strong><\/p>\n

var a = [3, 1, 2]\nlet b = a \/\/ a copy is made (but it will be copy-on-write)\na.sort() \/\/ mutating method\na \/\/ [1, 2, 3]\nb \/\/ [3, 1, 2]\n<\/code><\/pre>\n

Members of a struct that are declared as var, is still protected based on how the variable is declared.<\/p>\n

struct Event {\n    var count: Int \/\/ member count can be mutated\n\n    mutating func increment(_ amount: Int) {\n        count += amount\n    }\n}\n\nlet e = Event()\ne.increment(10) \/\/ This won't compile because the variable e is let\n<\/code><\/pre>\n

In order to mutate the member count<\/code> even though it has been declared as var balance<\/code> the variable doing the mutation needs to be declared with var<\/code><\/p>\n

var e = Event()\ne.increment(10) \/\/ This will now work because the variable is declared as var\n<\/code><\/pre>\n<\/div>\n","protected":false},"excerpt":{"rendered":"

Photo by Zbynek Burival on Unsplash […]<\/p>\n

Read more →<\/a><\/p>\n","protected":false},"author":2,"featured_media":228,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_mi_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[37],"tags":[36,25],"yoast_head":"\n100 Days of Learning: Day 4 \u2013 Using Environment variables and Secrets in OpenFaaS - Andr\u00e9 Jacobs<\/title>\n<meta name=\"description\" content=\"Day 4 of 100 complete. Today I learned about using Environment variables and Secrets with an OpenFaaS function.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-4-using-environment-variables-and-secrets-in-openfaas\/\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"100 Days of Learning: Day 4 \u2013 Using Environment variables and Secrets in OpenFaaS - Andr\u00e9 Jacobs\" \/>\n<meta property=\"og:description\" content=\"Day 4 of 100 complete. Today I learned about using Environment variables and Secrets with an OpenFaaS function.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-4-using-environment-variables-and-secrets-in-openfaas\/\" \/>\n<meta property=\"og:site_name\" content=\"Andr\u00e9 Jacobs\" \/>\n<meta property=\"article:published_time\" content=\"2021-03-12T20:57:55+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-04-11T20:24:23+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/andrejacobs.org\/wp-content\/uploads\/2021\/03\/zbynek-burival-V4ZYJZJ3W4M-unsplash.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1920\" \/>\n\t<meta property=\"og:image:height\" content=\"1272\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Andr\u00e9 Jacobs\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@andrejacobs81\" \/>\n<meta name=\"twitter:site\" content=\"@andrejacobs81\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Andr\u00e9 Jacobs\" \/>\n\t<meta name=\"twitter:label2\" content=\"Estimated reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-4-using-environment-variables-and-secrets-in-openfaas\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-4-using-environment-variables-and-secrets-in-openfaas\/\"},\"author\":{\"name\":\"Andr\u00e9 Jacobs\",\"@id\":\"https:\/\/andrejacobs.org\/#\/schema\/person\/3d38360883015e883c80c2fb875c5a68\"},\"headline\":\"100 Days of Learning: Day 4 \u2013 Using Environment variables and Secrets in OpenFaaS\",\"datePublished\":\"2021-03-12T20:57:55+00:00\",\"dateModified\":\"2022-04-11T20:24:23+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-4-using-environment-variables-and-secrets-in-openfaas\/\"},\"wordCount\":573,\"publisher\":{\"@id\":\"https:\/\/andrejacobs.org\/#\/schema\/person\/3d38360883015e883c80c2fb875c5a68\"},\"keywords\":[\"OpenFaaS\",\"swift\"],\"articleSection\":[\"100 Days Challenge\"],\"inLanguage\":\"en-GB\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-4-using-environment-variables-and-secrets-in-openfaas\/\",\"url\":\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-4-using-environment-variables-and-secrets-in-openfaas\/\",\"name\":\"100 Days of Learning: Day 4 \u2013 Using Environment variables and Secrets in OpenFaaS - Andr\u00e9 Jacobs\",\"isPartOf\":{\"@id\":\"https:\/\/andrejacobs.org\/#website\"},\"datePublished\":\"2021-03-12T20:57:55+00:00\",\"dateModified\":\"2022-04-11T20:24:23+00:00\",\"description\":\"Day 4 of 100 complete. Today I learned about using Environment variables and Secrets with an OpenFaaS function.\",\"breadcrumb\":{\"@id\":\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-4-using-environment-variables-and-secrets-in-openfaas\/#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-4-using-environment-variables-and-secrets-in-openfaas\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-4-using-environment-variables-and-secrets-in-openfaas\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/andrejacobs.org\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"100 Days of Learning: Day 4 \u2013 Using Environment variables and Secrets in OpenFaaS\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/andrejacobs.org\/#website\",\"url\":\"https:\/\/andrejacobs.org\/\",\"name\":\"Andr\u00e9 Jacobs\",\"description\":\"iOS Development, Electronics, Robotics, Artificial Intelligence, Business and Health\",\"publisher\":{\"@id\":\"https:\/\/andrejacobs.org\/#\/schema\/person\/3d38360883015e883c80c2fb875c5a68\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/andrejacobs.org\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-GB\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/andrejacobs.org\/#\/schema\/person\/3d38360883015e883c80c2fb875c5a68\",\"name\":\"Andr\u00e9 Jacobs\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\/\/andrejacobs.org\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/andrejacobs.org\/wp-content\/uploads\/2019\/03\/andre_jacobs.jpg\",\"contentUrl\":\"https:\/\/andrejacobs.org\/wp-content\/uploads\/2019\/03\/andre_jacobs.jpg\",\"width\":450,\"height\":450,\"caption\":\"Andr\u00e9 Jacobs\"},\"logo\":{\"@id\":\"https:\/\/andrejacobs.org\/#\/schema\/person\/image\/\"},\"sameAs\":[\"https:\/\/andrejacobs.org\",\"https:\/\/www.youtube.com\/channel\/UCzqXvnd_UJ3sAzQkQBD-IVw\"],\"url\":\"https:\/\/andrejacobs.org\/author\/andre\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"100 Days of Learning: Day 4 \u2013 Using Environment variables and Secrets in OpenFaaS - Andr\u00e9 Jacobs","description":"Day 4 of 100 complete. Today I learned about using Environment variables and Secrets with an OpenFaaS function.","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:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-4-using-environment-variables-and-secrets-in-openfaas\/","og_locale":"en_GB","og_type":"article","og_title":"100 Days of Learning: Day 4 \u2013 Using Environment variables and Secrets in OpenFaaS - Andr\u00e9 Jacobs","og_description":"Day 4 of 100 complete. Today I learned about using Environment variables and Secrets with an OpenFaaS function.","og_url":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-4-using-environment-variables-and-secrets-in-openfaas\/","og_site_name":"Andr\u00e9 Jacobs","article_published_time":"2021-03-12T20:57:55+00:00","article_modified_time":"2022-04-11T20:24:23+00:00","og_image":[{"width":1920,"height":1272,"url":"https:\/\/andrejacobs.org\/wp-content\/uploads\/2021\/03\/zbynek-burival-V4ZYJZJ3W4M-unsplash.jpg","type":"image\/jpeg"}],"author":"Andr\u00e9 Jacobs","twitter_card":"summary_large_image","twitter_creator":"@andrejacobs81","twitter_site":"@andrejacobs81","twitter_misc":{"Written by":"Andr\u00e9 Jacobs","Estimated reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-4-using-environment-variables-and-secrets-in-openfaas\/#article","isPartOf":{"@id":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-4-using-environment-variables-and-secrets-in-openfaas\/"},"author":{"name":"Andr\u00e9 Jacobs","@id":"https:\/\/andrejacobs.org\/#\/schema\/person\/3d38360883015e883c80c2fb875c5a68"},"headline":"100 Days of Learning: Day 4 \u2013 Using Environment variables and Secrets in OpenFaaS","datePublished":"2021-03-12T20:57:55+00:00","dateModified":"2022-04-11T20:24:23+00:00","mainEntityOfPage":{"@id":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-4-using-environment-variables-and-secrets-in-openfaas\/"},"wordCount":573,"publisher":{"@id":"https:\/\/andrejacobs.org\/#\/schema\/person\/3d38360883015e883c80c2fb875c5a68"},"keywords":["OpenFaaS","swift"],"articleSection":["100 Days Challenge"],"inLanguage":"en-GB"},{"@type":"WebPage","@id":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-4-using-environment-variables-and-secrets-in-openfaas\/","url":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-4-using-environment-variables-and-secrets-in-openfaas\/","name":"100 Days of Learning: Day 4 \u2013 Using Environment variables and Secrets in OpenFaaS - Andr\u00e9 Jacobs","isPartOf":{"@id":"https:\/\/andrejacobs.org\/#website"},"datePublished":"2021-03-12T20:57:55+00:00","dateModified":"2022-04-11T20:24:23+00:00","description":"Day 4 of 100 complete. Today I learned about using Environment variables and Secrets with an OpenFaaS function.","breadcrumb":{"@id":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-4-using-environment-variables-and-secrets-in-openfaas\/#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-4-using-environment-variables-and-secrets-in-openfaas\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-4-using-environment-variables-and-secrets-in-openfaas\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/andrejacobs.org\/"},{"@type":"ListItem","position":2,"name":"100 Days of Learning: Day 4 \u2013 Using Environment variables and Secrets in OpenFaaS"}]},{"@type":"WebSite","@id":"https:\/\/andrejacobs.org\/#website","url":"https:\/\/andrejacobs.org\/","name":"Andr\u00e9 Jacobs","description":"iOS Development, Electronics, Robotics, Artificial Intelligence, Business and Health","publisher":{"@id":"https:\/\/andrejacobs.org\/#\/schema\/person\/3d38360883015e883c80c2fb875c5a68"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/andrejacobs.org\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-GB"},{"@type":["Person","Organization"],"@id":"https:\/\/andrejacobs.org\/#\/schema\/person\/3d38360883015e883c80c2fb875c5a68","name":"Andr\u00e9 Jacobs","image":{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/andrejacobs.org\/#\/schema\/person\/image\/","url":"https:\/\/andrejacobs.org\/wp-content\/uploads\/2019\/03\/andre_jacobs.jpg","contentUrl":"https:\/\/andrejacobs.org\/wp-content\/uploads\/2019\/03\/andre_jacobs.jpg","width":450,"height":450,"caption":"Andr\u00e9 Jacobs"},"logo":{"@id":"https:\/\/andrejacobs.org\/#\/schema\/person\/image\/"},"sameAs":["https:\/\/andrejacobs.org","https:\/\/www.youtube.com\/channel\/UCzqXvnd_UJ3sAzQkQBD-IVw"],"url":"https:\/\/andrejacobs.org\/author\/andre\/"}]}},"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"https:\/\/andrejacobs.org\/wp-content\/uploads\/2021\/03\/zbynek-burival-V4ZYJZJ3W4M-unsplash.jpg","_links":{"self":[{"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/posts\/226"}],"collection":[{"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/comments?post=226"}],"version-history":[{"count":3,"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/posts\/226\/revisions"}],"predecessor-version":[{"id":230,"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/posts\/226\/revisions\/230"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/media\/228"}],"wp:attachment":[{"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/media?parent=226"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/categories?post=226"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/tags?post=226"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}