{"id":9456,"date":"2016-12-03T11:43:42","date_gmt":"2016-12-03T10:43:42","guid":{"rendered":"https:\/\/www.dbi-services.com\/blog\/can-i-do-it-with-postgresql-6-server-programming\/"},"modified":"2016-12-03T11:43:42","modified_gmt":"2016-12-03T10:43:42","slug":"can-i-do-it-with-postgresql-6-server-programming","status":"publish","type":"post","link":"https:\/\/www.dbi-services.com\/blog\/can-i-do-it-with-postgresql-6-server-programming\/","title":{"rendered":"Can I do it with PostgreSQL? \u2013 6 \u2013 Server programming"},"content":{"rendered":"<p>Today we&#8217;ll continue this series with another topic: What does PostgreSQL provide when it comes to server programming, that is: Writing functions and triggers to support your application? In <a href=\"http:\/\/docs.oracle.com\/database\/122\/LNPLS\/overview.htm#LNPLS001\" target=\"_blank\" rel=\"noopener\">Oracle you can either use PL\/SQL<\/a> or <a href=\"http:\/\/docs.oracle.com\/database\/122\/JJDEV\/installation-and-configuration.htm#JJDEV13214\" target=\"_blank\" rel=\"noopener\">Java<\/a>, in <a href=\"https:\/\/mariadb.com\/kb\/en\/mariadb\/programmatic-and-compound-statements\/\" target=\"_blank\" rel=\"noopener\">MariaDB you can use stored procedures written in SQL<\/a>, MS SQL Server provides <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/bb510741.aspx\" target=\"_blank\" rel=\"noopener\">Transact SQL<\/a> and with DB2 you can write stored procedures in a <a href=\"http:\/\/www.ibm.com\/support\/knowledgecenter\/SSEPEK_10.0.0\/apsg\/src\/tpc\/db2z_storedprocedure.html\" target=\"_blank\" rel=\"noopener\">host language or SQL<\/a>. <\/p>\n<p><!--more--><\/p>\n<p>We&#8217;ll use the same sample data as in the last post:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\nc postgres\ndrop database if exists ddl;\ncreate database ddl;\nc ddl\ncreate table t1 ( a int, b int );\ninsert into t1 (a,b)\n       values (generate_series(1,1000000)\n              ,generate_series(1,1000000));\nselect count(*) from t1;\ncreate index i1 on t1(a);\ncreate unique index i2 on t1(b);\ncreate view v1 as select a from t1;\nalter table t1 add constraint con1 check ( a &lt; 2000000 );\nd t1\n<\/pre>\n<p>So, what can you do? To begin with you can create functions containing pure SQL commands. These are called &#8220;query language functions&#8221;. You can for example do things like this (although this function is not very useful as can you do the same by just selecting the whole table):<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\nCREATE FUNCTION select_all_from_t1() RETURNS SETOF t1 AS '\n  SELECT * \n    FROM t1;\n' LANGUAGE SQL;\n<\/pre>\n<p>There are two important points here: The &#8220;LANGUAGE&#8221; part which means that the function is written in pure SQL. The keyword &#8220;SETOF&#8221; which means that we want to return a whole set of the rows of t1. Once the function is created you can use it in SQL:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\n(postgres@[local]:5439) [ddl] &gt; select select_all_from_t1();\n select_all_from_t1 \n--------------------\n (1,1)\n (2,2)\n (3,3)\n...\n<\/pre>\n<p>When you want to do something where it does not make sense to return anything you can do it by using the &#8220;VOID&#8221; keyword:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\nCREATE FUNCTION update_t1() RETURNS VOID AS '\n  UPDATE t1\n     SET a = 5\n   WHERE a &lt; 10\n&#039; LANGUAGE SQL;\n<\/pre>\n<p>When you execute this you do not get a result:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\n(postgres@[local]:5439) [ddl] &gt; select update_t1();\n update_t1 \n-----------\n NULL\n(1 row)\n(postgres@[local]:5439) [ddl] &gt; select count(*) from t1 where a = 5;\n count \n-------\n     9\n(1 row)\n<\/pre>\n<p>What about parameters? You can do this as well:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\nCREATE FUNCTION do_the_math(anumber1 numeric, anumber2 numeric ) RETURNS numeric AS '\n  SELECT do_the_math.anumber1 * do_the_math.anumber2;\n' LANGUAGE SQL;\n<\/pre>\n<p>Execute it:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\n(postgres@[local]:5439) [ddl] &gt; select do_the_math(1.1,1.2);\n do_the_math \n-------------\n        1.32\n<\/pre>\n<p>Another great feature is that you can have a variable\/dynamic amount of input parameters when you specify the input parameter as an array:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\nCREATE FUNCTION dynamic_input(VARIADIC arr numeric[]) RETURNS int AS $$\n    SELECT array_length($1,1);\n$$ LANGUAGE SQL;\n\n(postgres@[local]:5439) [ddl] &gt; select dynamic_input( 1,2,3,4 );\n dynamic_input \n---------------\n             4\n<\/pre>\n<p>So far for the SQL functions. What can you do when you need more than SQL? Then you can use the so called &#8220;procedural language functions&#8221;. One of these which is available by default is <a href=\"https:\/\/www.postgresql.org\/docs\/current\/static\/plpgsql.html\" target=\"_blank\" rel=\"noopener\">PL\/pgSQL<\/a>:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\n(postgres@[local]:5439) [ddl] &gt; dx\n                 List of installed extensions\n  Name   | Version |   Schema   |         Description          \n---------+---------+------------+------------------------------\n plpgsql | 1.0     | pg_catalog | PL\/pgSQL procedural language\n(1 row)\n<\/pre>\n<p>By using PL\/pgSQL you can add control structures around your SQL very much as you can do it in PL\/SQL (except that you cannot create packages).  <\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\nCREATE FUNCTION f1(int,int) RETURNS text AS $$\nDECLARE\n    t_row t1%ROWTYPE;\n    result text;\nBEGIN\n    SELECT * \n      INTO t_row\n      FROM t1\n     WHERE a = 99;\n    IF t_row.b &gt; 0\n    THEN\n        result := 'aaaaaa';\n    ELSE\n        result := 'bbbbbb';\n    END IF;\n    RETURN result;\nEND;\n$$ LANGUAGE plpgsql;\n(postgres@[local]:5439) [ddl] &gt; select f1(1,1);\n   f1   \n--------\n aaaaaa\n<\/pre>\n<p>You can also use anonymous blocks:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\n(postgres@[local]:5439) [ddl] &gt; DO $$\nBEGIN\n  FOR i IN 1..10\n  LOOP\n    raise notice 'blubb';\n  END LOOP;\nEND$$ LANGUAGE plpgsql;\nNOTICE:  blubb\nNOTICE:  blubb\nNOTICE:  blubb\nNOTICE:  blubb\nNOTICE:  blubb\nNOTICE:  blubb\nNOTICE:  blubb\nNOTICE:  blubb\nNOTICE:  blubb\nNOTICE:  blubb\nDO\n<\/pre>\n<p>Of course there is more than IF-THEN-ELSE which is documented <a href=\"https:\/\/www.postgresql.org\/docs\/current\/static\/plpgsql-control-structures.html\" target=\"_blank\" rel=\"noopener\">here<\/a>.<\/p>\n<p>So by now we know two options to write functions in PostgreSQL. Is there more we can do? Of course: You prefer to write your functions in <a href=\"https:\/\/www.postgresql.org\/docs\/current\/static\/plperl-funcs.html\">Perl<\/a>? <\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\n(postgres@[local]:5439) [ddl] &gt; create extension plperl;\nCREATE EXTENSION\n(postgres@[local]:5439) [ddl] &gt; dx\n                 List of installed extensions\n  Name   | Version |   Schema   |         Description          \n---------+---------+------------+------------------------------\n plperl  | 1.0     | pg_catalog | PL\/Perl procedural language\n plpgsql | 1.0     | pg_catalog | PL\/pgSQL procedural language\n\n\nCREATE FUNCTION perl_max (integer, integer) RETURNS integer AS $$\n    my ($x, $y) = @_;\n    if (not defined $x) {\n        return undef if not defined $y;\n        return $y;\n    }\n    return $x if not defined $y;\n    return $x if $x &gt; $y;\n    return $y;\n$$ LANGUAGE plperl;\n\n(postgres@[local]:5439) [ddl] &gt; select perl_max(1,2);\n perl_max \n----------\n        2\n<\/pre>\n<p>You prefer <a href=\"https:\/\/www.postgresql.org\/docs\/current\/static\/plpython.html\" target=\"_blank\" rel=\"noopener\">python<\/a>?<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\n(postgres@[local]:5439) [ddl] &gt; create extension plpythonu;\nCREATE EXTENSION\nTime: 327.434 ms\n(postgres@[local]:5439) [ddl] &gt; dx\n                        List of installed extensions\n   Name    | Version |   Schema   |               Description                \n-----------+---------+------------+------------------------------------------\n plperl    | 1.0     | pg_catalog | PL\/Perl procedural language\n plpgsql   | 1.0     | pg_catalog | PL\/pgSQL procedural language\n plpythonu | 1.0     | pg_catalog | PL\/PythonU untrusted procedural language\n\nCREATE FUNCTION pymax (a integer, b integer)\n  RETURNS integer\nAS $$\n  if a &gt; b:\n    return a\n  return b\n$$ LANGUAGE plpythonu;\n\n(postgres@[local]:5439) [ddl] &gt; select pymax(1,1);\n pymax \n-------\n     1\n<\/pre>\n<p>&#8230; or better <a href=\"https:\/\/www.postgresql.org\/docs\/current\/static\/pltcl.html\" target=\"_blank\" rel=\"noopener\">TcL<\/a>? <\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">\n(postgres@[local]:5439) [ddl] &gt; create extension pltclu;\nCREATE EXTENSION\nTime: 382.982 ms\n(postgres@[local]:5439) [ddl] &gt; dx\n                        List of installed extensions\n   Name    | Version |   Schema   |               Description                \n-----------+---------+------------+------------------------------------------\n plperl    | 1.0     | pg_catalog | PL\/Perl procedural language\n plpgsql   | 1.0     | pg_catalog | PL\/pgSQL procedural language\n plpythonu | 1.0     | pg_catalog | PL\/PythonU untrusted procedural language\n pltclu    | 1.0     | pg_catalog | PL\/TclU untrusted procedural language\n<\/pre>\n<p>And these are only the default extensions. There is much more you can <a href=\"https:\/\/www.postgresql.org\/docs\/current\/static\/external-pl.html\" target=\"_blank\" rel=\"noopener\">do<\/a>:<\/p>\n<ul>\n<li>Java<\/li>\n<li>PHP<\/li>\n<li>R<\/li>\n<li>Ruby<\/li>\n<li>Scheme<\/li>\n<li>Unix shell<\/li>\n<\/ul>\n<p>You see: PostgreSQL gives you the maximum flexibility \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Today we&#8217;ll continue this series with another topic: What does PostgreSQL provide when it comes to server programming, that is: Writing functions and triggers to support your application? In Oracle you can either use PL\/SQL or Java, in MariaDB you can use stored procedures written in SQL, MS SQL Server provides Transact SQL and with [&hellip;]<\/p>\n","protected":false},"author":28,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[229],"tags":[77],"type_dbi":[],"class_list":["post-9456","post","type-post","status-publish","format-standard","hentry","category-database-administration-monitoring","tag-postgresql"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v28.8 (Yoast SEO v28.8) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Can I do it with PostgreSQL? \u2013 6 \u2013 Server programming - dbi 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:\/\/www.dbi-services.com\/blog\/can-i-do-it-with-postgresql-6-server-programming\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Can I do it with PostgreSQL? \u2013 6 \u2013 Server programming\" \/>\n<meta property=\"og:description\" content=\"Today we&#8217;ll continue this series with another topic: What does PostgreSQL provide when it comes to server programming, that is: Writing functions and triggers to support your application? In Oracle you can either use PL\/SQL or Java, in MariaDB you can use stored procedures written in SQL, MS SQL Server provides Transact SQL and with [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.dbi-services.com\/blog\/can-i-do-it-with-postgresql-6-server-programming\/\" \/>\n<meta property=\"og:site_name\" content=\"dbi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2016-12-03T10:43:42+00:00\" \/>\n<meta name=\"author\" content=\"Open source Team\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Open source Team\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/can-i-do-it-with-postgresql-6-server-programming\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/can-i-do-it-with-postgresql-6-server-programming\\\/\"},\"author\":{\"name\":\"Open source Team\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/4bae5e5dd8c7d48edbd948772b49b202\"},\"headline\":\"Can I do it with PostgreSQL? \u2013 6 \u2013 Server programming\",\"datePublished\":\"2016-12-03T10:43:42+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/can-i-do-it-with-postgresql-6-server-programming\\\/\"},\"wordCount\":400,\"commentCount\":0,\"keywords\":[\"PostgreSQL\"],\"articleSection\":[\"Database Administration &amp; Monitoring\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/can-i-do-it-with-postgresql-6-server-programming\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/can-i-do-it-with-postgresql-6-server-programming\\\/\",\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/can-i-do-it-with-postgresql-6-server-programming\\\/\",\"name\":\"Can I do it with PostgreSQL? \u2013 6 \u2013 Server programming - dbi Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#website\"},\"datePublished\":\"2016-12-03T10:43:42+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/4bae5e5dd8c7d48edbd948772b49b202\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/can-i-do-it-with-postgresql-6-server-programming\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/can-i-do-it-with-postgresql-6-server-programming\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/can-i-do-it-with-postgresql-6-server-programming\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Can I do it with PostgreSQL? \u2013 6 \u2013 Server programming\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/\",\"name\":\"dbi Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/4bae5e5dd8c7d48edbd948772b49b202\",\"name\":\"Open source Team\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/eb4fb12e386e8c41fdef0733e8114594cf2653e4f55e9fa2161442b8eaf3f657?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/eb4fb12e386e8c41fdef0733e8114594cf2653e4f55e9fa2161442b8eaf3f657?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/eb4fb12e386e8c41fdef0733e8114594cf2653e4f55e9fa2161442b8eaf3f657?s=96&d=mm&r=g\",\"caption\":\"Open source Team\"},\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/author\\\/open-source-team\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Can I do it with PostgreSQL? \u2013 6 \u2013 Server programming - dbi 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:\/\/www.dbi-services.com\/blog\/can-i-do-it-with-postgresql-6-server-programming\/","og_locale":"en_US","og_type":"article","og_title":"Can I do it with PostgreSQL? \u2013 6 \u2013 Server programming","og_description":"Today we&#8217;ll continue this series with another topic: What does PostgreSQL provide when it comes to server programming, that is: Writing functions and triggers to support your application? In Oracle you can either use PL\/SQL or Java, in MariaDB you can use stored procedures written in SQL, MS SQL Server provides Transact SQL and with [&hellip;]","og_url":"https:\/\/www.dbi-services.com\/blog\/can-i-do-it-with-postgresql-6-server-programming\/","og_site_name":"dbi Blog","article_published_time":"2016-12-03T10:43:42+00:00","author":"Open source Team","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Open source Team","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.dbi-services.com\/blog\/can-i-do-it-with-postgresql-6-server-programming\/#article","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/can-i-do-it-with-postgresql-6-server-programming\/"},"author":{"name":"Open source Team","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/4bae5e5dd8c7d48edbd948772b49b202"},"headline":"Can I do it with PostgreSQL? \u2013 6 \u2013 Server programming","datePublished":"2016-12-03T10:43:42+00:00","mainEntityOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/can-i-do-it-with-postgresql-6-server-programming\/"},"wordCount":400,"commentCount":0,"keywords":["PostgreSQL"],"articleSection":["Database Administration &amp; Monitoring"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.dbi-services.com\/blog\/can-i-do-it-with-postgresql-6-server-programming\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.dbi-services.com\/blog\/can-i-do-it-with-postgresql-6-server-programming\/","url":"https:\/\/www.dbi-services.com\/blog\/can-i-do-it-with-postgresql-6-server-programming\/","name":"Can I do it with PostgreSQL? \u2013 6 \u2013 Server programming - dbi Blog","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/#website"},"datePublished":"2016-12-03T10:43:42+00:00","author":{"@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/4bae5e5dd8c7d48edbd948772b49b202"},"breadcrumb":{"@id":"https:\/\/www.dbi-services.com\/blog\/can-i-do-it-with-postgresql-6-server-programming\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.dbi-services.com\/blog\/can-i-do-it-with-postgresql-6-server-programming\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.dbi-services.com\/blog\/can-i-do-it-with-postgresql-6-server-programming\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.dbi-services.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Can I do it with PostgreSQL? \u2013 6 \u2013 Server programming"}]},{"@type":"WebSite","@id":"https:\/\/www.dbi-services.com\/blog\/#website","url":"https:\/\/www.dbi-services.com\/blog\/","name":"dbi Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/4bae5e5dd8c7d48edbd948772b49b202","name":"Open source Team","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/eb4fb12e386e8c41fdef0733e8114594cf2653e4f55e9fa2161442b8eaf3f657?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/eb4fb12e386e8c41fdef0733e8114594cf2653e4f55e9fa2161442b8eaf3f657?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/eb4fb12e386e8c41fdef0733e8114594cf2653e4f55e9fa2161442b8eaf3f657?s=96&d=mm&r=g","caption":"Open source Team"},"url":"https:\/\/www.dbi-services.com\/blog\/author\/open-source-team\/"}]}},"_links":{"self":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/9456","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/users\/28"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/comments?post=9456"}],"version-history":[{"count":0,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/9456\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media?parent=9456"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/categories?post=9456"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/tags?post=9456"},{"taxonomy":"type","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/type_dbi?post=9456"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}