{"id":301115,"date":"2020-04-01T21:00:16","date_gmt":"2020-04-01T21:00:16","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=301115"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=301115","title":{"rendered":"5NO \u2014 NodeJS ORM for Postgres"},"content":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/495242\/\">\n<h4>\u041a\u0440\u0430\u0442\u043a\u043e \u043e\u0431 \u044d\u0442\u043e\u043c \u043c\u043e\u0434\u0443\u043b\u0435<\/h4>\n<p>  \u042d\u0442\u043e\u0442 \u043c\u043e\u0434\u0443\u043b\u044c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d \u043c\u043d\u043e\u0439 \u0434\u043b\u044f \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043c\u0435\u0436\u0434\u0443 Postgres \u0438 JS.<br \/>  \u042f \u043f\u043e\u043d\u0438\u043c\u0430\u044e \u0447\u0442\u043e \u0435\u0441\u0442\u044c \u043c\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u0439, \u043d\u043e \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0447\u0442\u043e \u0442\u043e \u0433\u0438\u0431\u043a\u043e\u0435 \u0438 \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u0432 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u043d\u0443\u0436\u0434. <\/p>\n<p>  \u041c\u043e\u0434\u0443\u043b\u044c \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u0442 \u0432 \u0441\u0435\u0431\u0435 \u0442\u0440\u0438 \u0432\u0430\u0436\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438: \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044e \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u043e\u0441\u0442\u0440\u043e\u0439\u043a\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0432 \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0432\u044b\u0432\u043e\u0434 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 JSON.<br \/>  <a name=\"habracut\"><\/a>  <\/p>\n<h4>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0441\u0430\u043c\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f <\/h4>\n<p>  <\/p>\n<pre><code class=\"bash\">npm install --save @5no\/pg-model <\/code><\/pre>\n<p>  <\/p>\n<h4>\u041d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 <\/h4>\n<p>  <\/p>\n<pre><code class=\"plaintext\">DATABASE_URL=postgres:\/\/test:123123@127.0.0.1:5432\/testDB?ssl=false DATABASE_QUERY_LOG=true <\/code><\/pre>\n<p>  <\/p>\n<h4>\u0414\u0430\u043b\u044c\u0448\u0435 \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445<\/h4>\n<p>  \u0422\u0430\u043b\u0438\u0446\u0430 \u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c\u0438:<\/p>\n<pre><code class=\"pgsql\">CREATE TABLE &quot;public&quot;.&quot;users&quot; ( \t&quot;id&quot; uuid NOT NULL DEFAULT uuid_generate_v4(), \t&quot;email&quot; text NOT NULL COLLATE &quot;default&quot;,         &quot;personalised&quot; jsonb DEFAULT '{}'::jsonb, \t&quot;properties&quot; jsonb DEFAULT '[]'::jsonb, \t&quot;created_at&quot; timestamp(6) WITH TIME ZONE NOT NULL DEFAULT now(), \t&quot;updated_at&quot; timestamp(6) WITH TIME ZONE NOT NULL DEFAULT now() ) <\/code><\/pre>\n<p>  \u0422\u0430\u0431\u043b\u0438\u0446\u0430 \u0441 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435:<\/p>\n<pre><code class=\"pgsql\">CREATE TABLE &quot;public&quot;.&quot;users_info&quot; ( \t&quot;id&quot; uuid NOT NULL DEFAULT uuid_generate_v4(), \t&quot;user_id&quot; uuid NOT NULL, \t&quot;first_name&quot; text COLLATE &quot;default&quot;, \t&quot;last_name&quot; text COLLATE &quot;default&quot;, \t&quot;created_at&quot; timestamp(6) WITH TIME ZONE NOT NULL DEFAULT now(), \t&quot;updated_at&quot; timestamp(6) WITH TIME ZONE NOT NULL DEFAULT now() ) <\/code><\/pre>\n<p>  \u0422\u0430\u0431\u043b\u0438\u0446\u0430 \u0441 \u0430\u0434\u0440\u0435\u0441\u0430\u043c\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f:<\/p>\n<pre><code class=\"pgsql\">CREATE TABLE &quot;public&quot;.&quot;users_address&quot; ( \t&quot;id&quot; uuid NOT NULL DEFAULT uuid_generate_v4(), \t&quot;user_id&quot; uuid NOT NULL, \t&quot;street_name&quot; text COLLATE &quot;default&quot;, \t&quot;postcode&quot; text COLLATE &quot;default&quot;, \t&quot;created_at&quot; timestamp(6) WITH TIME ZONE NOT NULL DEFAULT now(), \t&quot;updated_at&quot; timestamp(6) WITH TIME ZONE NOT NULL DEFAULT now() ) <\/code><\/pre>\n<p>  \u0422\u0430\u0431\u043b\u0438\u0446\u0430 \u0441 \u0440\u043e\u043b\u044f\u043c\u0438:<\/p>\n<pre><code class=\"pgsql\">CREATE TABLE &quot;public&quot;.&quot;roles&quot; ( \t&quot;id&quot; uuid NOT NULL DEFAULT uuid_generate_v4(), \t&quot;role&quot; text NULL, \t&quot;created_at&quot; timestamp(6) WITH TIME ZONE NOT NULL DEFAULT now(), \t&quot;updated_at&quot; timestamp(6) WITH TIME ZONE NOT NULL DEFAULT now() ) <\/code><\/pre>\n<p>  \u0422\u0430\u0431\u043b\u0438\u0446\u0430 \u0441\u0432\u044f\u0437\u0438 \u0440\u043e\u043b\u0438 \u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f:<\/p>\n<pre><code class=\"pgsql\">CREATE TABLE &quot;public&quot;.&quot;user_roles&quot; ( \t&quot;user_id&quot; uuid NOT NULL, \t&quot;role_id&quot; uuid NOT NULL ) <\/code><\/pre>\n<p>  <\/p>\n<h4>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043c\u043e\u0434\u0435\u043b\u0435\u0439<\/h4>\n<p>  \u041c\u043e\u0434\u0435\u043b\u044c \u0440\u043e\u043b\u0435\u0439:<\/p>\n<pre><code class=\"javascript\">const { Model } = require('@5no\/pg-model')  class Roles extends Model {   static schema = {     table: {       schema: 'public',       name: 'roles',     },     columns: {       id: {         type: String,         primaryKey: true,         defaultValue: null,       },       role: {         type: String,         defaultValue: null,       },       created_at: {         type: Date,         created: true,         format: 'YYYY-MM-DD HH:mm:ss',       },       updated_at: {         type: Date,         updated: true,         format: 'YYYY-MM-DD HH:mm:ss',       },     },     relations: {},   } } <\/code><\/pre>\n<p>  \u041c\u043e\u0434\u0435\u043b\u044c \u0441\u0432\u044f\u0437\u0438 \u0440\u043e\u043b\u0435\u0439 \u043a \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e:<\/p>\n<pre><code class=\"javascript\">const { Model } = require('@5no\/pg-model')  class UserRoles extends Model {   static schema = {     table: {       schema: 'public',       name: 'user_roles',     },     columns: {       user_id: {         type: String,         defaultValue: null,         primaryKey: true,       },       role_id: {         type: String,         defaultValue: null,         primaryKey: true,       },     },     relations: {},   } } <\/code><\/pre>\n<p>  \u041c\u043e\u0434\u0435\u043b\u044c \u0430\u0434\u0440\u0435\u0441\u043e\u0432 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f:<\/p>\n<pre><code class=\"javascript\">const { Model } = require('@5no\/pg-model')  class UsersAddresses extends Model {     static schema = {       table: {         schema: 'public',         name: 'users_address',       },       columns: {         id: {           type: String,           primaryKey: true,           defaultValue: null,         },         user_id: {           type: String,           defaultValue: null,           required: true,         },         street_name: {           type: String,           defaultValue: null,         },         postcode: {           type: String,           defaultValue: null,         },         created_at: {           type: Date,           created: true,           format: 'YYYY-MM-DD HH:mm:ss',         },         updated_at: {           type: Date,           updated: true,           format: 'YYYY-MM-DD HH:mm:ss',         },       },       relations: {},     } } <\/code><\/pre>\n<p>  \u041c\u043e\u0434\u0435\u043b\u044c \u0441 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0435\u0439 \u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435:<\/p>\n<pre><code class=\"javascript\">const { Model } = require('@5no\/pg-model')  class UsersInfo extends Model {     static schema = {       table: {         schema: 'public',         name: 'users_info',       },       columns: {         id: {           type: String,           primaryKey: true,           defaultValue: null,         },         user_id: {           type: String,           defaultValue: null,           required: true,         },         first_name: {           type: String,           defaultValue: null,         },         last_name: {           type: String,           defaultValue: null,         },         created_at: {           type: Date,           created: true,           format: 'YYYY-MM-DD HH:mm:ss',         },         updated_at: {           type: Date,           updated: true,           format: 'YYYY-MM-DD HH:mm:ss',         },       },       relations: {},     } } <\/code><\/pre>\n<p>  \u041c\u043e\u0434\u0435\u043b\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f:<\/p>\n<pre><code class=\"javascript\">const { Model } = require('@5no\/pg-model')  class Users extends Model {     static schema = {       table: {         schema: 'public',         name: 'users',       },       columns: {         id: {           type: String,           primaryKey: true,           defaultValue: null,         },         email: {           type: String,           required: true,           validators: [             'email',           ],         },         personalised: {           type: Object,           prefilled: true,           defaultValue: {             test: 100,           },         },         countRoles: {           type: Function,           fn: (model) =&gt; Manager.build(UserRoles).count('user_id', model.id),         },         properties: {           type: Array,           defaultValue: [],           schema: {             name: {               type: String,               required: true,               filters: [                 'lowerCase',               ],             },             value: {               type: String,               required: true,             },           },         },         created_at: {           type: Date,           created: true,           format: 'YYYY-MM-DD HH:mm:ss',         },         updated_at: {           type: Date,           updated: true,           format: 'YYYY-MM-DD HH:mm:ss',         },       },       relations: {         Info: {           model: UsersInfo,           local: 'id',           foreign: 'user_id',           type: 'one',           cascade: [             'save',             'delete',           ],         },         Addresses: {           model: UsersAddresses,           local: 'id',           foreign: 'user_id',           type: 'many',           cascade: [             'save',             'delete',           ],         },         Roles: {           model: UserRoles,           join: {             model: Roles,             local: 'role_id',             foreign: 'id',             type: 'many',           },           local: 'id',           foreign: 'user_id',           type: 'join',           cascade: [             'save',             'delete',           ],         },       },     } } <\/code><\/pre>\n<p>  <\/p>\n<h4>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u043e\u0434\u0435\u043b\u0435\u0439<\/h4>\n<p>  \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0440\u043e\u043b\u0435\u0439:<\/p>\n<pre><code class=\"javascript\">const role = new Roles() role.role = 'Admin' await role.save() <\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"javascript\">const role = new Roles() role.role = 'Customer' await role.save() <\/code><\/pre>\n<p>  \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f:<\/p>\n<pre><code class=\"javascript\">const user = new Users()  user.email = 'test@test.test' await user.Addresses.add({         street_name: 'Test',         postcode: '100500',  }) await user.Addresses.add({         street_name: 'Test 2',         postcode: '100502',  })   user.Info.first_name = 'Test First Name' user.Info.last_name = 'Test Last Name'  user.properties = [         {           name: 'Test',           value: 'OK',         }, ]  await user.Roles.join(CustomerRoleId)  await user.save() <\/code><\/pre>\n<p>  \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0437\u0430\u043f\u0438\u0441\u0438:<\/p>\n<pre><code class=\"javascript\">const { Manager } = require('@5no\/pg-model')  const user = await Manager.build(Users).find(usersId)  await user.Roles.join(AdminRoleId)  await user.save() <\/code><\/pre>\n<p>  \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u0432\u0438\u0434\u0435 JSON:<\/p>\n<pre><code class=\"javascript\">const { Manager } = require('@5no\/pg-model')  const userJsonData = await Manager.build(Users, true).find(usersId)  console.log(userJsonData) <\/code><\/pre>\n<p>  \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<pre><code class=\"json\">{    id: '7852468e-ac99-4f5e-9ee3-d506b0c4424e',   email: 'test@test.test',   countRoles: 2,   created_at: '2018-12-20 17:10:31',   updated_at: '2018-12-20 17:10:31',   personalised: {     test: 100   },   properties: [     {       name: 'test',       value: 'OK',     },   ],   Info:     { id: '0320dc4f-4ca7-4b65-bd42-52f286a0b9db',      user_id: '7852468e-ac99-4f5e-9ee3-d506b0c4424e',      first_name: 'Test First Name',      last_name: 'Test Last Name',      created_at: '2018-12-20 17:10:31',      updated_at: '2018-12-20 17:10:31' },   Addresses:     [       { id: 'be40ccb3-3a33-4b6e-9467-6907b0c4396b',        user_id: '7852468e-ac99-4f5e-9ee3-d506b0c4424e',        street_name: 'Test',        postcode: '100500',        created_at: '2018-12-20 17:10:31',        updated_at: '2018-12-20 17:10:31' },      { id: 'f5bae3e9-290b-451e-a0e2-1ec2d9eaf543',        user_id: '7852468e-ac99-4f5e-9ee3-d506b0c4424e',        street_name: 'Test 2',        postcode: '100502',        created_at: '2018-12-20 17:10:31',        updated_at: '2018-12-20 17:10:31' }      ],    Roles: [     {       created_at: '2018-12-20 17:10:31',       id: 'be40ccb3-3a33-4b6e-9467-6907b0c4396b',       role: 'Admin',       updated_at: '2018-12-20 17:10:31'     },     {       created_at: '2018-12-20 17:10:31',       id: 'be40ccb3-3a33-4b6e-9467-7907b1c4396b',       role: 'Customer',       updated_at: '2018-12-20 17:10:31'     }   ] } <\/code><\/pre>\n<p>  \u0412 \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0445\u043e\u0442\u0435\u043b \u0431\u044b \u0441\u043a\u0430\u0437\u0430\u0442\u044c \u0447\u0442\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043b \u0434\u043b\u044f \u0441\u0435\u0431\u044f \u0438 \u0441\u0432\u043e\u0438\u0445 \u043d\u0443\u0436\u0434 \u0438 \u0441\u0434\u0435\u043b\u0430\u043b \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0433\u0438\u0431\u043a\u043e\u0439. <\/p>\n<p>  <a href=\"https:\/\/5no.io\/pg-model\/examples\">\u0412\u0441\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0435\u0441\u0442\u044c \u043d\u0430 \u0441\u0430\u0439\u0442\u0435<\/a><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/495242\/\"> https:\/\/habr.com\/ru\/post\/495242\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/495242\/\">\n<h4>\u041a\u0440\u0430\u0442\u043a\u043e \u043e\u0431 \u044d\u0442\u043e\u043c \u043c\u043e\u0434\u0443\u043b\u0435<\/h4>\n<p>  \u042d\u0442\u043e\u0442 \u043c\u043e\u0434\u0443\u043b\u044c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d \u043c\u043d\u043e\u0439 \u0434\u043b\u044f \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043c\u0435\u0436\u0434\u0443 Postgres \u0438 JS.<br \/>  \u042f \u043f\u043e\u043d\u0438\u043c\u0430\u044e \u0447\u0442\u043e \u0435\u0441\u0442\u044c \u043c\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u0439, \u043d\u043e \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0447\u0442\u043e \u0442\u043e \u0433\u0438\u0431\u043a\u043e\u0435 \u0438 \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u0432 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u043d\u0443\u0436\u0434. <\/p>\n<p>  \u041c\u043e\u0434\u0443\u043b\u044c \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u0442 \u0432 \u0441\u0435\u0431\u0435 \u0442\u0440\u0438 \u0432\u0430\u0436\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438: \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044e \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u043e\u0441\u0442\u0440\u043e\u0439\u043a\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0432 \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0432\u044b\u0432\u043e\u0434 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 JSON.  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-301115","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/301115","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=301115"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/301115\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=301115"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=301115"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=301115"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}