{"id":2971,"date":"2018-04-09T12:32:27","date_gmt":"2018-04-09T18:32:27","guid":{"rendered":"http:\/\/www.mooreds.com\/wordpress\/?p=2971"},"modified":"2021-10-30T08:55:27","modified_gmt":"2021-10-30T14:55:27","slug":"using-wordpress-as-a-crud-database-api-included","status":"publish","type":"post","link":"https:\/\/www.mooreds.com\/wordpress\/archives\/2971","title":{"rendered":"Using WordPress as a CRUD Database, API Included"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" class=\"alignright size-medium wp-image-2973\" src=\"http:\/\/www.mooreds.com\/wordpress\/wp-content\/uploads\/2018\/04\/lan-3290669_640-300x225.jpg\" alt=\"Ethernet cord\" width=\"300\" height=\"225\" srcset=\"http:\/\/edit.mooreds.com\/wordpress\/wp-content\/uploads\/2018\/04\/lan-3290669_640-300x225.jpg 300w, http:\/\/edit.mooreds.com\/wordpress\/wp-content\/uploads\/2018\/04\/lan-3290669_640.jpg 640w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/>Based on this <a href=\"https:\/\/news.ycombinator.com\/item?id=16508965\">HN discussion<\/a>, which I <a href=\"http:\/\/www.mooreds.com\/wordpress\/archives\/2818\">discussed a while back<\/a>, I looked at how to set up WP as a CRUD database accessible via API.<\/p>\n<p>It wasn&#8217;t hard. Steps:<\/p>\n<ol>\n<li>Install WordPress (I used ec2 and the <a href=\"https:\/\/docs.aws.amazon.com\/AWSCloudFormation\/latest\/UserGuide\/sample-templates-applications-us-east-1.html\">Cloudformation sample template<\/a>)<\/li>\n<li>Install the following plugins\n<ul>\n<li><a href=\"https:\/\/wordpress.org\/plugins\/advanced-custom-fields\/\">Advanced Custom Fields<\/a><\/li>\n<li><a href=\"https:\/\/wordpress.org\/plugins\/acf-to-rest-api\/\">ACF to REST API<\/a><\/li>\n<li><a href=\"https:\/\/wordpress.org\/plugins\/custom-post-type-ui\/\">Custom Post Type UI<\/a><\/li>\n<\/ul>\n<\/li>\n<li>I also installed the following optional plugins\n<ul>\n<li><a href=\"https:\/\/github.com\/WP-API\/Basic-Auth\">Json Basic Auth<\/a> to protect the API during development<\/li>\n<li><a href=\"https:\/\/wordpress.org\/plugins\/registered-users-only\/\">Registered Users Only<\/a> to protect the entire website<\/li>\n<\/ul>\n<\/li>\n<li>I created a custom post type of &#8216;todo&#8217; and added a couple of custom fields.<\/li>\n<li>I was able to get the todos by going to these URLs (apparently you can have the API live at wp-json, but that required <a href=\"https:\/\/stackoverflow.com\/questions\/23842235\/wordpress-jsonapi-wp-json-was-not-found-on-this-server\">some rejiggering of url permalinks<\/a>).\n<ul>\n<li>http:\/\/host\/wordpress\/?rest_route=\/wp\/v2\/todo\/8<\/li>\n<li>http:\/\/host\/wordpress\/?rest_route=\/wp\/v2\/todos<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p>Here&#8217;s an example of the output:<\/p>\n<pre>{\r\n  \"id\": 8,\r\n  \"date\": \"2018-03-05T02:38:26\",\r\n  \"date_gmt\": \"2018-03-05T02:38:26\",\r\n  \"guid\": {\r\n    \"rendered\": \"http:\/\/host\/wordpress\/?post_type=todo&amp;p=8\"\r\n  },\r\n  \"modified\": \"2018-03-05T02:40:01\",\r\n  \"modified_gmt\": \"2018-03-05T02:40:01\",\r\n  \"slug\": \"auto-draft\",\r\n  \"status\": \"publish\",\r\n  \"type\": \"todo\",\r\n  \"link\": \"http:\/\/host\/wordpress\/todo\/auto-draft\/\",\r\n  \"title\": {\r\n    \"rendered\": \"Buy Milk\"\r\n  },\r\n  \"template\": \"\",\r\n  \"acf\": {\r\n    \"\": false,\r\n    \"due_date\": \"20180308\",\r\n    \"description\": \"please buy milk.\",\r\n    \"who_owns_it\": {\r\n      \"ID\": \"1\",\r\n      \"user_firstname\": \"\",\r\n      \"user_lastname\": \"\",\r\n      \"nickname\": \"mooreds\",\r\n      \"user_nicename\": \"mooreds\",\r\n      \"display_name\": \"mooreds\",\r\n      \"user_email\": \"...\",\r\n      \"user_url\": \"\",\r\n      \"user_registered\": \"2018-03-05 02:21:36\",\r\n      \"user_description\": \"\",\r\n      \"user_avatar\": \"...\"\r\n    },\r\n    \"done\": false\r\n  },\r\n  \"_links\": {\r\n    \"self\": [\r\n      {\r\n        \"href\": \"http:\/\/host\/wordpress\/wp-json\/wp\/v2\/todo\/8\"\r\n      }\r\n    ],\r\n    \"collection\": [\r\n      {\r\n        \"href\": \"http:\/\/host\/wordpress\/wp-json\/wp\/v2\/todo\"\r\n      }\r\n    ],\r\n    \"about\": [\r\n      {\r\n        \"href\": \"http:\/\/host\/wordpress\/wp-json\/wp\/v2\/types\/todo\"\r\n      }\r\n    ],\r\n    \"wp:attachment\": [\r\n      {\r\n        \"href\": \"http:\/\/host\/wordpress\/wp-json\/wp\/v2\/media?parent=8\"\r\n      }\r\n    ],\r\n    \"curies\": [\r\n      {\r\n        \"name\": \"wp\",\r\n        \"href\": \"https:\/\/api.w.org\/{rel}\",\r\n        \"templated\": true\r\n      }\r\n    ]\r\n  }\r\n}\r\n\r\n<\/pre>\n<p>The custom post fields are all under the ACF key, and you can see that there was an expansion of the <code>who_owns_it<\/code> field. If you are going to do this, make sure have the the normal <code>title<\/code> tag be part of the custom post, otherwise the WP UX for editing the custom posts won&#8217;t be much use.<\/p>\n<p>Not perfectly restful, but a super simple way to set up an API that non technical folks can use to create, update or delete records and that you can consume in other systems.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Based on this HN discussion, which I discussed a while back, I looked at how to set up WP as a CRUD database accessible via API. It wasn&#8217;t hard. Steps: [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[62,33,20],"tags":[],"class_list":["post-2971","post","type-post","status-publish","format-standard","hentry","category-apis","category-useful-tools","category-web-applications"],"_links":{"self":[{"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/posts\/2971","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/comments?post=2971"}],"version-history":[{"count":2,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/posts\/2971\/revisions"}],"predecessor-version":[{"id":2974,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/posts\/2971\/revisions\/2974"}],"wp:attachment":[{"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/media?parent=2971"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/categories?post=2971"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/tags?post=2971"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}