{"id":330381,"date":"2022-03-07T09:00:08","date_gmt":"2022-03-07T09:00:08","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=330381"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=330381","title":{"rendered":"<span>\u0413\u0435\u043a\u0441\u0430\u0433\u043e\u043d\u0430\u043b\u044c\u043d\u0430\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u0438 Domain Driven Design \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 Front-end \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/73d\/388\/6c1\/73d3886c1bd1ece8caa65d0a5cc7d8b2.png\" width=\"1353\" height=\"537\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/73d\/388\/6c1\/73d3886c1bd1ece8caa65d0a5cc7d8b2.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041d\u0435 \u0441\u0442\u043e\u0438\u0442 \u0432\u043e\u0441\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u044c\u044e \u0437\u0430 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432\u0435\u0440\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434. \u0412\u0430\u0440\u0438\u0430\u0446\u0438\u0439 \u043c\u043d\u043e\u0433\u043e, \u044d\u0442\u043e \u0432\u0441\u0435 \u043b\u0438\u0448\u044c \u0432\u0438\u0434\u0435\u043d\u0438\u0435 \u0430\u0432\u0442\u043e\u0440\u0430 \u043d\u0430 \u0442\u0435\u043c\u0430\u0442\u0438\u043a\u0443 \u0432\u043e\u043f\u0440\u043e\u0441\u0430.<\/p>\n<h2>\u041f\u043e\u0433\u0440\u0443\u0436\u0435\u043d\u0438\u0435<\/h2>\n<p>Domain Driven Design &#8212; \u044d\u0442\u043e \u043d\u0430\u0431\u043e\u0440 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u043e\u0432 \u0438 \u0441\u0445\u0435\u043c, \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u043d\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432. \u041e\u043d \u0441\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u044b\u0445 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043c\u043e\u0434\u0435\u043b\u044f\u043c\u0438 \u043f\u0440\u0435\u0434\u043c\u0435\u0442\u043d\u044b\u0445 \u043e\u0431\u043b\u0430\u0441\u0442\u0435\u0439. \u0412 \u044d\u0442\u0438 \u043c\u043e\u0434\u0435\u043b\u0438 \u0432\u0445\u043e\u0434\u0438\u0442 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0430, \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u044e\u0449\u0430\u044f \u0441\u0432\u044f\u0437\u044c \u043c\u0435\u0436\u0434\u0443 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u043c\u0438 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430 \u0438 \u043a\u043e\u0434\u043e\u043c.<\/p>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u044d\u0442\u043e\u00a0 \u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0446\u0438\u0438, \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0438, \u0441\u0445\u0435\u043c\u044b, \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u044b \u043d\u0430\u0448\u0435\u0433\u043e \u0431\u0443\u0434\u0443\u0449\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f typescript \u0432 \u0434\u043e\u043c\u0435\u043d\u0435, \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u044b \u0438 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438, \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b. \u0414\u0430\u043b\u0435\u0435 \u0432\u0441\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0441\u044f \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 application \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438. \u0412 \u0434\u043e\u043c\u0435\u043d \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u043f\u0440\u043e\u043d\u0438\u043a\u0430\u0442\u044c \u0438\u0437\u0432\u043d\u0435 &#8212; \u043e\u043d \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u043e\u043c \u0447\u0438\u0441\u0442\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0443 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u0438.<\/p>\n<p>\u0413\u0435\u043a\u0441\u0430\u0433\u043e\u043d\u0430\u043b\u044c\u043d\u0430\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u0440\u0430\u0431\u043e\u0442\u044b \u0410\u043b\u0438\u0441\u0442\u0435\u0440\u0430 \u041a\u043e\u043a\u0431\u0435\u0440\u043d\u0430. \u042d\u0442\u043e \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043d\u044b\u0439 \u0448\u0430\u0431\u043b\u043e\u043d, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439.<\/p>\n<p>\u041e\u0441\u043d\u043e\u0432\u0430 \u0434\u0430\u043d\u043d\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b &#8212; \u043f\u043e\u0440\u0442\u044b \u0438 \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u044b.<\/p>\n<p><strong>\u041f\u043e\u0440\u0442\u044b<\/strong> &#8212; \u044d\u0442\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u044b \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f,<\/p>\n<p><strong>\u0410\u0434\u0430\u043f\u0442\u0435\u0440\u044b<\/strong> &#8212;\u00a0 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0430\u0448\u0438\u0445 \u043f\u043e\u0440\u0442\u043e\u0432.<\/p>\n<p>\u0413<strong>\u0435\u043a\u0441\u0430\u0433\u043e\u043d<\/strong> &#8212; \u0444\u0438\u0433\u0443\u0440\u0430, \u0438\u043c\u0435\u044e\u0449\u0430\u044f 6 \u0441\u0442\u043e\u0440\u043e\u043d, \u0448\u0435\u0441\u0442\u0438\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0441\u043b\u043e\u0438\u0441\u0442\u0430\u044f \u0438\u043b\u0438 \u043c\u043d\u043e\u0433\u043e\u0433\u0440\u0430\u043d\u043d\u0430\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430.<\/p>\n<p><strong>\u041f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430:<\/strong><\/p>\n<ol>\n<li>\n<p>\u041d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c: \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043d\u0435 \u0437\u0430\u0446\u0438\u043a\u043b\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0431\u0438\u0437\u043d\u0435\u0441 \u043b\u043e\u0433\u0438\u043a\u0435.<br \/>\u041c\u043e\u0436\u043d\u043e \u0437\u0430\u0434\u0435\u043a\u043b\u0430\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0445\u0435\u043c\u0443 \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u00a0\u0434\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u043c\u043e\u043a\u0430\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p>\u0413\u0438\u0431\u043a\u043e\u0441\u0442\u044c: \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043b\u044e\u0431\u044b\u0445 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432, \u043f\u0435\u0440\u0435\u043d\u043e\u0441 \u0434\u043e\u043c\u0435\u043d\u043e\u0432 \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u043e\u0432 \u0432 \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u044b, \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u044b\u0445 \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u043e\u0432 \u0431\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430.<\/p>\n<\/li>\n<\/ol>\n<ol start=\"3\">\n<li>\n<p>\u041b\u0435\u0433\u043a\u0430\u044f \u0438\u0437\u043c\u0435\u043d\u0447\u0438\u0432\u043e\u0441\u0442\u044c: \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u043e\u0434\u043d\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0435 \u0432\u043b\u0438\u044f\u044e\u0442 \u043d\u0430 \u0434\u0440\u0443\u0433\u0438\u0435 \u043e\u0431\u043b\u0430\u0441\u0442\u0438.<\/p>\n<\/li>\n<\/ol>\n<p><strong>\u041c\u0438\u043d\u0443\u0441\u044b<\/strong><\/p>\n<p>\u041f\u043e\u0433\u0440\u0443\u0436\u0435\u043d\u0438\u0435: \u043c\u043d\u043e\u0433\u0438\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0441\u043b\u043e\u0436\u043d\u043e \u043e\u0441\u0432\u043e\u0438\u0442\u044c\u0441\u044f, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e, \u043f\u0440\u0438 \u043d\u0435\u0432\u044b\u0441\u043e\u043a\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435 \u0437\u043d\u0430\u043d\u0438\u0439. \u0414\u043e\u043b\u0433\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u044f \u0441\u0430\u043c \u043e\u0442\u0442\u043e\u0440\u0433\u0430\u043b \u0434\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434, \u0441\u0441\u044b\u043b\u0430\u044f\u0441\u044c \u043d\u0430 \u0435\u0433\u043e \u0438\u0437\u0431\u044b\u0442\u043e\u0447\u043d\u043e\u0441\u0442\u044c, \u043f\u043e\u043a\u0430 \u043d\u0435 \u043e\u0441\u0432\u043e\u0438\u043b \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043c\u0435\u0441\u044f\u0446\u0435\u0432.<\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043c\u043e\u0433\u0443\u0442 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0443\u0442\u044c \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441 graphql.<\/p>\n<hr\/>\n<h2>\u041a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435?<\/h2>\n<p><strong>\u041f\u043e\u0440\u0442\u044b<\/strong><\/p>\n<p>\u041f\u043e\u0440\u0442\u044b \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u044b\u043c\u0438 (\u0432\u0445\u043e\u0434\u044f\u0449\u0438\u043c\u0438) primary \u0438 \u0432\u0442\u043e\u0440\u0438\u0447\u043d\u044b\u043c\u0438 (\u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u043c\u0438) secondary &#8212;\u00a0 \u044d\u0442\u043e \u0441\u0432\u044f\u0437\u0438 \u043c\u0435\u0436\u0434\u0443 \u0432\u043d\u0435\u0448\u043d\u0438\u043c \u043c\u0438\u0440\u043e\u043c \u0438 \u044f\u0434\u0440\u043e\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.\u00a0<\/p>\n<p>\u041f\u0435\u0440\u0432\u0438\u0447\u043d\u044b\u0435\u00a0 \u043f\u043e\u0440\u0442\u044b \u2014 \u044d\u0442\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u044e\u0449\u0438\u0435 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 http, api, \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u0431\u0434.\u00a0<\/p>\n<p>\u0412\u0442\u043e\u0440\u0438\u0447\u043d\u044b\u0435 \u043f\u043e\u0440\u0442\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u044f\u0434\u0440\u043e\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0432\u043d\u0435\u0448\u043d\u0438\u043c \u0441\u043b\u0443\u0436\u0431\u0430\u043c.<\/p>\n<p>\u0422\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0438 \u0438 \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0443\u0440\u043e\u0432\u043d\u0435\u0439. \u041f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0441\u0442\u0435\u043a\u0430 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 \u043a\u043e\u0434 \u0434\u043e\u043c\u0435\u043d\u0430 \u043e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f \u043f\u0440\u0435\u0436\u043d\u0438\u043c. \u042f\u0434\u0440\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043e\u0441\u043d\u043e\u0432\u043d\u0443\u044e \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0443 \u0438 \u0431\u0438\u0437\u043d\u0435\u0441-\u043f\u0440\u0430\u0432\u0438\u043b\u0430.<\/p>\n<p><strong>\u0410\u0434\u0430\u043f\u0442\u0435\u0440\u044b<\/strong><\/p>\n<p>\u0410\u0434\u0430\u043f\u0442\u0435\u0440\u044b \u0441\u043b\u0443\u0436\u0430\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u043d\u0430\u0448\u0438\u0445 \u043f\u043e\u0440\u0442\u043e\u0432. \u0415\u0441\u0442\u044c \u0434\u0432\u0430 \u0442\u0438\u043f\u0430 \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u043e\u0432: \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u044b\u0439 \u0438 \u0432\u0442\u043e\u0440\u0438\u0447\u043d\u044b\u0439 &#8212; \u043f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441 \u043f\u043e\u0440\u0442\u0430\u043c\u0438.<\/p>\n<p>\u041a \u043f\u0440\u0438\u043c\u0435\u0440\u0443, \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u044b, \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0441 \u0432\u0435\u0431-\u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043e\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0442 \u0432\u0442\u043e\u0440\u0438\u0447\u043d\u044b\u0439 \u043f\u043e\u0440\u0442, \u0430 \u0442\u0435 \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u044e\u0442 \u0441\u0432\u044f\u0437\u044c \u0441 \u0432\u043d\u0435\u0448\u043d\u0438\u043c \u043c\u0438\u0440\u043e\u043c (api), \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0442 \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u044b\u0439 \u043f\u043e\u0440\u0442.<\/p>\n<p>\u041f\u043e\u0440\u0442\u044b \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u043d\u0430\u043c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u044b \u043a \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c\u0443 \u0434\u043e\u043c\u0435\u043d\u0443.<\/p>\n<hr\/>\n<h2>\u041e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u044f \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435<\/h2>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/152\/81e\/c19\/15281ec19da45db4b01e39f828bb467e.png\" width=\"2530\" height=\"757\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/152\/81e\/c19\/15281ec19da45db4b01e39f828bb467e.png\"\/><figcaption><\/figcaption><\/figure>\n<p><strong>INFRASTRUCTURE<\/strong> &#8212; \u044d\u0442\u043e \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0430<\/p>\n<p><strong>Adapter<\/strong> &#8212; \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u044b\u0439 primary (pr) \u043f\u043e\u0440\u0442, \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u0442 \u0432\u043d\u0435\u0448\u043d\u0438\u0439 \u043c\u0438\u0440 \u0441 \u0434\u043e\u043c\u0435\u043d\u043e\u043c<\/p>\n<p><strong>Services<\/strong> &#8212; \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0432\u0442\u043e\u0440\u0438\u0447\u043d\u044b\u0439 secondary (sec), \u0430\u0434\u0430\u043f\u0442\u0435\u0440 \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u0442 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441 \u0434\u043e\u043c\u0435\u043d\u043e\u043c (\u0432 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u0445 \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043d\u044b\u043c api)<\/p>\n<p><strong>Schema<\/strong> &#8212; \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u0440\u0438\u0448\u0435\u0434\u0448\u0438\u0445 \u043e\u0442 INFRASTRUCTURE.\u00a0\u0412 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432 DTO \u0434\u043b\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432 Entities<\/p>\n<p><strong>Commands<\/strong> &#8212; \u0432\u0445\u043e\u0434\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u043e\u0432<\/p>\n<p><strong>Controller<\/strong> &#8212; \u0417\u0430\u0432\u0438\u0441\u044f\u0442 \u043e\u0442 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430. \u042d\u0442\u043e \u0442\u043e, \u0447\u0442\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0441\u0435\u0440\u0432\u0438\u0441, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 vuex \u0438\u043b\u0438 redux \u0431\u0443\u0434\u0435\u0442 actions<\/p>\n<hr\/>\n<h2>\u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u043a\u043e\u0434\u0443<\/h2>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0434\u043b\u044f \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u043b\u0435\u043d\u0438\u044f <a href=\"https:\/\/github.com\/jtapes\/geksagon-architecture-domain-driven-design\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/github.com\/jtapes\/geksagon-architecture-domain-driven-design<\/u><\/a><\/p>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/4de\/727\/86e\/4de72786e3ac64e582b4243a68ef95e9.png\" width=\"407\" height=\"882\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/4de\/727\/86e\/4de72786e3ac64e582b4243a68ef95e9.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0432 \u043d\u0430\u0448\u0435\u043c \u0434\u043e\u043c\u0435\u043d\u0435.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043f\u0440\u043e\u0434\u0443\u043a\u0442 \u043d\u0430\u0448\u0435\u0433\u043e \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0430:<\/p>\n<pre><code class=\"javascript\">export type ProductId = string; export type ProductName = string; export type ProductPrice = number;  export class ProductEntity {   constructor(     private readonly _id: ProductId,     private readonly _name: ProductName,     private readonly _price: ProductPrice   ) {}    \/* istanbul ignore next *\/   public get id() {     return this._id;   }    \/* istanbul ignore next *\/   public get name() {     return this._name;   }    \/* istanbul ignore next *\/   public get price() {     return this._price;   } } <\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043b\u0438\u0441\u0442\u0438\u043d\u0433 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u0432:<\/p>\n<pre><code class=\"javascript\">import { ProductEntity } from \".\/ProductEntity\";  export class ProductListEntity {   constructor(protected readonly _products: ProductEntity[] = []) {}    \/* istanbul ignore next *\/   get products() {     return this._products;   }    get namesLog() {     return this._products.map((product) => product.name).join(\" \");   } } <\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043c\u0435\u0442\u043e\u0434\u044b \u0438\u043b\u0438 \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u0433\u0435\u0442\u0442\u0435\u0440\u044b \u0438 \u0441\u0435\u0442\u0442\u0435\u0440\u044b, \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u044e \u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0435\u0441\u0442\u044b:<\/p>\n<pre><code class=\"javascript\">import { ProductListingMock } from \"..\/..\/..\/application\/mocks\/ProductListingMock\";  describe(\"Testing ProductListEntity\", () => {   test(\"get namesLog\", () => {     expect(ProductListingMock.namesLog === \"snickers mars kinder\").toBeTruthy();   }); }); <\/code><\/pre>\n<p>\u043f\u0440\u0438\u043c\u0435\u0440 \u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439.<\/p>\n<p>\u0414\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043c\u043e\u043a\u0438. \u0422\u0430\u043a\u0436\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u0434\u043b\u044f \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438, \u0438\u043b\u0438 \u0432 \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u044b\u0445 \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u0430\u0445, \u043f\u043e\u043a\u0430 \u0433\u043e\u0442\u043e\u0432\u044f\u0442\u0441\u044f \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0430 \u0431\u044d\u043a\u0435\u043d\u0434\u0435.<\/p>\n<pre><code class=\"javascript\">import { ProductListEntity } from \"..\/..\/domain\/product\/ProductListEntity\"; import { ProductEntity } from \"..\/..\/domain\/product\/ProductEntity\";  export const ProductListingMock = new ProductListEntity([   new ProductEntity(\"1\", \"snickers\", 60),   new ProductEntity(\"2\", \"mars\", 80),   new ProductEntity(\"3\", \"kinder\", 120), ]); <\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u043e\u0433\u043e \u043f\u043e\u0440\u0442\u0430 ProductLoadPort \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437\u0432\u043d\u0435:<\/p>\n<pre><code class=\"javascript\">import { Either } from \"@sweet-monads\/either\"; import { ErrorEntity } from \"..\/ErrorEntity\"; import { ProductListEntity } from \".\/ProductListEntity\"; import { ProductLoadCommand } from \".\/ProductLoadCommand\"; export interface ProductLoadPort {   load(command: ProductLoadCommand): Either&lt;ErrorEntity, ProductListEntity>; }<\/code><\/pre>\n<p>\u041d\u0430 \u0432\u0445\u043e\u0434 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 ProductLoadCommand \u0438 \u043e\u0442\u0434\u0430\u0435\u043c ProductListEnitity \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0443\u0441\u043f\u0435\u0445\u0430 \u0438\u043b\u0438 ErrorEntities \u043f\u0440\u0438 \u043e\u0448\u0438\u0431\u043a\u0435.<\/p>\n<p>ProductLoadCommand:<\/p>\n<pre><code class=\"javascript\">import { ProductId } from \".\/ProductEntity\";  export class ProductLoadCommand {   constructor(     private readonly _ids: ProductId[],     private readonly _lang: string = \"ru\"   ) {}    public get ids(): ProductId[] {     return this._ids;   }    public get lang(): ProductId {     return this._lang;   } } <\/code><\/pre>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u044d\u0442\u043e\u0442 \u043f\u043e\u0440\u0442 \u0432 \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u043e\u043c \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u0435:<\/p>\n<pre><code class=\"javascript\">import { ProductLoadPort } from \"..\/..\/..\/domain\/product\/ProductLoadPort\"; import { ProductLoadCommand } from \"..\/..\/..\/domain\/product\/ProductLoadCommand\"; import { productsMapper } from \"..\/..\/mappers\/ProductMapper\"; import { ProductsResponseSchema } from \"..\/..\/schema\/ProductsSchema\"; import { right, left } from \"@sweet-monads\/either\"; import { ErrorEntity } from \"..\/..\/..\/domain\/ErrorEntity\"; import { AxiosType } from \"..\/..\/..\/types\/AxiosType\";  export class ProductLoadAdapter implements ProductLoadPort {   api(command: ProductLoadCommand): AxiosType {     const responseJson = process.api.products.filter((product) => {       return command.ids.includes(product.id);     });     return {       data: responseJson as unknown,       code: 200,     };   }    load(command: ProductLoadCommand) {     const response = this.api(command);     const valid = ProductsResponseSchema.safeParse(response.data);     return valid.success       ? right(productsMapper(valid.data))       : left(new ErrorEntity(\"productLoad\", valid.error));   } } <\/code><\/pre>\n<p>\u041c\u0435\u0442\u043e\u0434 api \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0435 \u0434\u043b\u044f \u043d\u0430\u0441 \u0434\u0430\u043d\u043d\u044b\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443\u00a0 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0430\u043b\u0438\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u043f\u043e \u0441\u0445\u0435\u043c\u0435:<\/p>\n<p>ProductsResponseSchema<\/p>\n<pre><code class=\"javascript\">import { z } from \"zod\";  export const ProductsResponseSchema = z.array(   z.object({     id: z.string().max(2),     title: z.string(),     price: z.number().max(1000),   }) ); export type ProductsResponseSchemaType = z.infer&lt;typeof ProductsResponseSchema>; <\/code><\/pre>\n<pre><code class=\"javascript\"> const valid = ProductsResponseSchema.safeParse(response.data);<\/code><\/pre>\n<p>\u0435\u0441\u043b\u0438 valid.success = true,\u00a0 \u0432\u044b\u0437\u043e\u0432\u0435\u043c DTO (mapper)\u00a0<\/p>\n<p>productMapper:<\/p>\n<pre><code class=\"javascript\">import { ProductEntity } from \"..\/..\/domain\/product\/ProductEntity\"; import { ProductListEntity } from \"..\/..\/domain\/product\/ProductListEntity\"; import { ProductsResponseSchemaType } from \"..\/schema\/ProductsSchema\";  export function productsMapper(   response: ProductsResponseSchemaType ): ProductListEntity {   return new ProductListEntity(     response.map(       (product) => new ProductEntity(product.id, product.title, product.price)     )   ); }<\/code><\/pre>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u043c\u044b \u0443\u0436\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043b\u0438, \u0447\u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u043c\u0435\u0442\u043e\u0434\u0430 api \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0442\u0438\u043f\u0443 ProductsResponseSchemaType (valid.success = true),<\/p>\n<p>\u0432 productMapper \u043e\u0448\u0438\u0431\u043e\u043a \u043d\u0435 \u0431\u0443\u0434\u0435\u0442.<\/p>\n<p>\u0412 productMapper \u043b\u0438\u0448\u044c \u043e\u0434\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435, \u043f\u043e\u043b\u0435 title \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0432 name.<\/p>\n<p>\u041f\u0435\u0440\u0432\u0438\u0447\u043d\u044b\u0439 \u0430\u0434\u0430\u043f\u0442\u0435\u0440 \u0433\u043e\u0442\u043e\u0432!<\/p>\n<p>\u041f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u0432\u0442\u043e\u0440\u0438\u0447\u043d\u043e\u043c\u0443 \u043f\u043e\u0440\u0442\u0443, \u0433\u0434\u0435 \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0443\u0444\u0444\u0438\u043a\u0441\u044b Query \u0434\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0438 UseCase \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/c26\/cfc\/dd8\/c26cfcdd8450eb1eb1d011ee0a65f125.png\" width=\"623\" height=\"224\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c26\/cfc\/dd8\/c26cfcdd8450eb1eb1d011ee0a65f125.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043f\u043e\u0440\u0442\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0432\u0442\u043e\u0440\u0438\u0447\u043d\u044b\u0439 \u0430\u0434\u0430\u043f\u0442\u0435\u0440 (\u0441\u0435\u0440\u0432\u0438\u0441):<\/p>\n<pre><code class=\"javascript\">import { ProductLoadQuery } from \"..\/..\/..\/domain\/product\/ProductLoadQuery\"; import { ProductLoadCommand } from \"..\/..\/..\/domain\/product\/ProductLoadCommand\"; import { ProductLoadAdapter } from \"..\/..\/adapters\/product\/ProductLoad\"; import { ProductId } from \"..\/..\/..\/domain\/product\/ProductEntity\";  export class ProductLoadService implements ProductLoadQuery {   productLoadPort = new ProductLoadAdapter();    localization() {     \/\/ mock browser api     const navigator = {       language: \"en-EN\",     };     const userLang = navigator.language;     switch (userLang) {       case \"ru-RU\":         return \"ru\";       case \"en-EN\":         return \"en\";       default:         return \"ru\";     }   }    load(ids: ProductId[]) {     const command = new ProductLoadCommand(ids, this.localization());     return this.productLoadPort.load(command);   } } <\/code><\/pre>\n<p>\u0412\u043e \u0432\u0442\u043e\u0440\u0438\u0447\u043d\u043e\u043c \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043d\u043e\u0435 api, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043b\u043e\u043a\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u044b.<\/p>\n<p>\u041a\u0430\u043a \u0432\u0438\u0434\u043d\u043e, \u0432\u0442\u043e\u0440\u0438\u0447\u043d\u044b\u0439 \u0430\u0434\u0430\u043f\u0442\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0432\u044b\u0437\u043e\u0432 \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u043e\u0433\u043e \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u0430 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p>\u041d\u0430\u043f\u0440\u043e\u0442\u0438\u0432, \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u044b\u0439 \u0430\u0434\u0430\u043f\u0442\u0435\u0440 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u043f\u0440\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043b\u0430\u0441\u0441\u0430 \u0432\u0442\u043e\u0440\u0438\u0447\u043d\u043e\u0433\u043e \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u0430 (service).\u042d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u043a\u043b\u0430\u0441\u0441 \u0447\u0438\u0441\u0442\u044b\u043c. \u0412 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0432 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u00a0 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u043a\u0438\u0434\u044b\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u044b\u0439 \u0430\u0434\u0430\u043f\u0442\u0435\u0440 \u0432\u043e \u0432\u0442\u043e\u0440\u0438\u0447\u043d\u044b\u0439. \u041a\u0430\u0436\u0434\u044b\u0439 \u0432\u043e\u043b\u0435\u043d \u0432\u044b\u0431\u0438\u0440\u0430\u0442\u044c \u0443\u0434\u043e\u0431\u043d\u0443\u044e \u0434\u043b\u044f \u043d\u0435\u0433\u043e \u0441\u0445\u0435\u043c\u0443.<\/p>\n<hr\/>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>\u0414\u0430\u043d\u043d\u044b\u0435 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438 \u043f\u043e\u043c\u043e\u0433\u0443\u0442 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043a\u043e\u0434 \u0431\u043e\u043b\u0435\u0435 \u0447\u0438\u0441\u0442\u044b\u043c \u0438 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u043c \u043e\u0442 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432 \u0438 \u0432\u043d\u0435\u0448\u043d\u0435\u0433\u043e \u043c\u0438\u0440\u0430. \u041d\u0435 \u0441\u0442\u043e\u0438\u0442 \u0437\u0430\u0431\u044b\u0432\u0430\u0442\u044c, \u0447\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430 \u0441\u0435\u0440\u044c\u0435\u0437\u043d\u0430\u044f \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u043e\u0439 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438 \u0432 \u043f\u043e\u043b\u043d\u043e\u0439 \u043c\u0435\u0440\u0435.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"v-portal\" style=\"display:none;\"><\/div>\n<\/div>\n<p> <!----> <!----><br \/> \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\/654629\/\"> https:\/\/habr.com\/ru\/post\/654629\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u041d\u0435 \u0441\u0442\u043e\u0438\u0442 \u0432\u043e\u0441\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u044c\u044e \u0437\u0430 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432\u0435\u0440\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434. \u0412\u0430\u0440\u0438\u0430\u0446\u0438\u0439 \u043c\u043d\u043e\u0433\u043e, \u044d\u0442\u043e \u0432\u0441\u0435 \u043b\u0438\u0448\u044c \u0432\u0438\u0434\u0435\u043d\u0438\u0435 \u0430\u0432\u0442\u043e\u0440\u0430 \u043d\u0430 \u0442\u0435\u043c\u0430\u0442\u0438\u043a\u0443 \u0432\u043e\u043f\u0440\u043e\u0441\u0430.<\/p>\n<h2>\u041f\u043e\u0433\u0440\u0443\u0436\u0435\u043d\u0438\u0435<\/h2>\n<p>Domain Driven Design &#8212; \u044d\u0442\u043e \u043d\u0430\u0431\u043e\u0440 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u043e\u0432 \u0438 \u0441\u0445\u0435\u043c, \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u043d\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432. \u041e\u043d \u0441\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u044b\u0445 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043c\u043e\u0434\u0435\u043b\u044f\u043c\u0438 \u043f\u0440\u0435\u0434\u043c\u0435\u0442\u043d\u044b\u0445 \u043e\u0431\u043b\u0430\u0441\u0442\u0435\u0439. \u0412 \u044d\u0442\u0438 \u043c\u043e\u0434\u0435\u043b\u0438 \u0432\u0445\u043e\u0434\u0438\u0442 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0430, \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u044e\u0449\u0430\u044f \u0441\u0432\u044f\u0437\u044c \u043c\u0435\u0436\u0434\u0443 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u043c\u0438 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430 \u0438 \u043a\u043e\u0434\u043e\u043c.<\/p>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u044d\u0442\u043e\u00a0 \u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0446\u0438\u0438, \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0438, \u0441\u0445\u0435\u043c\u044b, \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u044b \u043d\u0430\u0448\u0435\u0433\u043e \u0431\u0443\u0434\u0443\u0449\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f typescript \u0432 \u0434\u043e\u043c\u0435\u043d\u0435, \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u044b \u0438 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438, \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b. \u0414\u0430\u043b\u0435\u0435 \u0432\u0441\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0441\u044f \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 application \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438. \u0412 \u0434\u043e\u043c\u0435\u043d \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u043f\u0440\u043e\u043d\u0438\u043a\u0430\u0442\u044c \u0438\u0437\u0432\u043d\u0435 &#8212; \u043e\u043d \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u043e\u043c \u0447\u0438\u0441\u0442\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0443 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u0438.<\/p>\n<p>\u0413\u0435\u043a\u0441\u0430\u0433\u043e\u043d\u0430\u043b\u044c\u043d\u0430\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u0440\u0430\u0431\u043e\u0442\u044b \u0410\u043b\u0438\u0441\u0442\u0435\u0440\u0430 \u041a\u043e\u043a\u0431\u0435\u0440\u043d\u0430. \u042d\u0442\u043e \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043d\u044b\u0439 \u0448\u0430\u0431\u043b\u043e\u043d, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439.<\/p>\n<p>\u041e\u0441\u043d\u043e\u0432\u0430 \u0434\u0430\u043d\u043d\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b &#8212; \u043f\u043e\u0440\u0442\u044b \u0438 \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u044b.<\/p>\n<p><strong>\u041f\u043e\u0440\u0442\u044b<\/strong> &#8212; \u044d\u0442\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u044b \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f,<\/p>\n<p><strong>\u0410\u0434\u0430\u043f\u0442\u0435\u0440\u044b<\/strong> &#8212;\u00a0 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0430\u0448\u0438\u0445 \u043f\u043e\u0440\u0442\u043e\u0432.<\/p>\n<p>\u0413<strong>\u0435\u043a\u0441\u0430\u0433\u043e\u043d<\/strong> &#8212; \u0444\u0438\u0433\u0443\u0440\u0430, \u0438\u043c\u0435\u044e\u0449\u0430\u044f 6 \u0441\u0442\u043e\u0440\u043e\u043d, \u0448\u0435\u0441\u0442\u0438\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0441\u043b\u043e\u0438\u0441\u0442\u0430\u044f \u0438\u043b\u0438 \u043c\u043d\u043e\u0433\u043e\u0433\u0440\u0430\u043d\u043d\u0430\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430.<\/p>\n<p><strong>\u041f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430:<\/strong><\/p>\n<ol>\n<li>\n<p>\u041d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c: \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043d\u0435 \u0437\u0430\u0446\u0438\u043a\u043b\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0431\u0438\u0437\u043d\u0435\u0441 \u043b\u043e\u0433\u0438\u043a\u0435.<br \/>\u041c\u043e\u0436\u043d\u043e \u0437\u0430\u0434\u0435\u043a\u043b\u0430\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0445\u0435\u043c\u0443 \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u00a0\u0434\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u043c\u043e\u043a\u0430\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p>\u0413\u0438\u0431\u043a\u043e\u0441\u0442\u044c: \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043b\u044e\u0431\u044b\u0445 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432, \u043f\u0435\u0440\u0435\u043d\u043e\u0441 \u0434\u043e\u043c\u0435\u043d\u043e\u0432 \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u043e\u0432 \u0432 \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u044b, \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u044b\u0445 \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u043e\u0432 \u0431\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430.<\/p>\n<\/li>\n<\/ol>\n<ol start=\"3\">\n<li>\n<p>\u041b\u0435\u0433\u043a\u0430\u044f \u0438\u0437\u043c\u0435\u043d\u0447\u0438\u0432\u043e\u0441\u0442\u044c: \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u043e\u0434\u043d\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0435 \u0432\u043b\u0438\u044f\u044e\u0442 \u043d\u0430 \u0434\u0440\u0443\u0433\u0438\u0435 \u043e\u0431\u043b\u0430\u0441\u0442\u0438.<\/p>\n<\/li>\n<\/ol>\n<p><strong>\u041c\u0438\u043d\u0443\u0441\u044b<\/strong><\/p>\n<p>\u041f\u043e\u0433\u0440\u0443\u0436\u0435\u043d\u0438\u0435: \u043c\u043d\u043e\u0433\u0438\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0441\u043b\u043e\u0436\u043d\u043e \u043e\u0441\u0432\u043e\u0438\u0442\u044c\u0441\u044f, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e, \u043f\u0440\u0438 \u043d\u0435\u0432\u044b\u0441\u043e\u043a\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435 \u0437\u043d\u0430\u043d\u0438\u0439. \u0414\u043e\u043b\u0433\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u044f \u0441\u0430\u043c \u043e\u0442\u0442\u043e\u0440\u0433\u0430\u043b \u0434\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434, \u0441\u0441\u044b\u043b\u0430\u044f\u0441\u044c \u043d\u0430 \u0435\u0433\u043e \u0438\u0437\u0431\u044b\u0442\u043e\u0447\u043d\u043e\u0441\u0442\u044c, \u043f\u043e\u043a\u0430 \u043d\u0435 \u043e\u0441\u0432\u043e\u0438\u043b \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043c\u0435\u0441\u044f\u0446\u0435\u0432.<\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043c\u043e\u0433\u0443\u0442 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0443\u0442\u044c \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441 graphql.<\/p>\n<hr\/>\n<h2>\u041a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435?<\/h2>\n<p><strong>\u041f\u043e\u0440\u0442\u044b<\/strong><\/p>\n<p>\u041f\u043e\u0440\u0442\u044b \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u044b\u043c\u0438 (\u0432\u0445\u043e\u0434\u044f\u0449\u0438\u043c\u0438) primary \u0438 \u0432\u0442\u043e\u0440\u0438\u0447\u043d\u044b\u043c\u0438 (\u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u043c\u0438) secondary &#8212;\u00a0 \u044d\u0442\u043e \u0441\u0432\u044f\u0437\u0438 \u043c\u0435\u0436\u0434\u0443 \u0432\u043d\u0435\u0448\u043d\u0438\u043c \u043c\u0438\u0440\u043e\u043c \u0438 \u044f\u0434\u0440\u043e\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.\u00a0<\/p>\n<p>\u041f\u0435\u0440\u0432\u0438\u0447\u043d\u044b\u0435\u00a0 \u043f\u043e\u0440\u0442\u044b \u2014 \u044d\u0442\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u044e\u0449\u0438\u0435 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 http, api, \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u0431\u0434.\u00a0<\/p>\n<p>\u0412\u0442\u043e\u0440\u0438\u0447\u043d\u044b\u0435 \u043f\u043e\u0440\u0442\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u044f\u0434\u0440\u043e\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0432\u043d\u0435\u0448\u043d\u0438\u043c \u0441\u043b\u0443\u0436\u0431\u0430\u043c.<\/p>\n<p>\u0422\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0438 \u0438 \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0443\u0440\u043e\u0432\u043d\u0435\u0439. \u041f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0441\u0442\u0435\u043a\u0430 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 \u043a\u043e\u0434 \u0434\u043e\u043c\u0435\u043d\u0430 \u043e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f \u043f\u0440\u0435\u0436\u043d\u0438\u043c. \u042f\u0434\u0440\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043e\u0441\u043d\u043e\u0432\u043d\u0443\u044e \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0443 \u0438 \u0431\u0438\u0437\u043d\u0435\u0441-\u043f\u0440\u0430\u0432\u0438\u043b\u0430.<\/p>\n<p><strong>\u0410\u0434\u0430\u043f\u0442\u0435\u0440\u044b<\/strong><\/p>\n<p>\u0410\u0434\u0430\u043f\u0442\u0435\u0440\u044b \u0441\u043b\u0443\u0436\u0430\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u043d\u0430\u0448\u0438\u0445 \u043f\u043e\u0440\u0442\u043e\u0432. \u0415\u0441\u0442\u044c \u0434\u0432\u0430 \u0442\u0438\u043f\u0430 \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u043e\u0432: \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u044b\u0439 \u0438 \u0432\u0442\u043e\u0440\u0438\u0447\u043d\u044b\u0439 &#8212; \u043f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441 \u043f\u043e\u0440\u0442\u0430\u043c\u0438.<\/p>\n<p>\u041a \u043f\u0440\u0438\u043c\u0435\u0440\u0443, \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u044b, \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0441 \u0432\u0435\u0431-\u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043e\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0442 \u0432\u0442\u043e\u0440\u0438\u0447\u043d\u044b\u0439 \u043f\u043e\u0440\u0442, \u0430 \u0442\u0435 \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u044e\u0442 \u0441\u0432\u044f\u0437\u044c \u0441 \u0432\u043d\u0435\u0448\u043d\u0438\u043c \u043c\u0438\u0440\u043e\u043c (api), \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0442 \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u044b\u0439 \u043f\u043e\u0440\u0442.<\/p>\n<p>\u041f\u043e\u0440\u0442\u044b \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u043d\u0430\u043c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u044b \u043a \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c\u0443 \u0434\u043e\u043c\u0435\u043d\u0443.<\/p>\n<hr\/>\n<h2>\u041e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u044f \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435<\/h2>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p><strong>INFRASTRUCTURE<\/strong> &#8212; \u044d\u0442\u043e \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0430<\/p>\n<p><strong>Adapter<\/strong> &#8212; \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u044b\u0439 primary (pr) \u043f\u043e\u0440\u0442, \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u0442 \u0432\u043d\u0435\u0448\u043d\u0438\u0439 \u043c\u0438\u0440 \u0441 \u0434\u043e\u043c\u0435\u043d\u043e\u043c<\/p>\n<p><strong>Services<\/strong> &#8212; \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0432\u0442\u043e\u0440\u0438\u0447\u043d\u044b\u0439 secondary (sec), \u0430\u0434\u0430\u043f\u0442\u0435\u0440 \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u0442 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441 \u0434\u043e\u043c\u0435\u043d\u043e\u043c (\u0432 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u0445 \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043d\u044b\u043c api)<\/p>\n<p><strong>Schema<\/strong> &#8212; \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u0440\u0438\u0448\u0435\u0434\u0448\u0438\u0445 \u043e\u0442 INFRASTRUCTURE.\u00a0\u0412 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432 DTO \u0434\u043b\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432 Entities<\/p>\n<p><strong>Commands<\/strong> &#8212; \u0432\u0445\u043e\u0434\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u043e\u0432<\/p>\n<p><strong>Controller<\/strong> &#8212; \u0417\u0430\u0432\u0438\u0441\u044f\u0442 \u043e\u0442 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430. \u042d\u0442\u043e \u0442\u043e, \u0447\u0442\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0441\u0435\u0440\u0432\u0438\u0441, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 vuex \u0438\u043b\u0438 redux \u0431\u0443\u0434\u0435\u0442 actions<\/p>\n<hr\/>\n<h2>\u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u043a\u043e\u0434\u0443<\/h2>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0434\u043b\u044f \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u043b\u0435\u043d\u0438\u044f <a href=\"https:\/\/github.com\/jtapes\/geksagon-architecture-domain-driven-design\" rel=\"noopener noreferrer nofollow\"><u>https:\/\/github.com\/jtapes\/geksagon-architecture-domain-driven-design<\/u><\/a><\/p>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0432 \u043d\u0430\u0448\u0435\u043c \u0434\u043e\u043c\u0435\u043d\u0435.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043f\u0440\u043e\u0434\u0443\u043a\u0442 \u043d\u0430\u0448\u0435\u0433\u043e \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0430:<\/p>\n<pre><code class=\"javascript\">export type ProductId = string; export type ProductName = string; export type ProductPrice = number;  export class ProductEntity {   constructor(     private readonly _id: ProductId,     private readonly _name: ProductName,     private readonly _price: ProductPrice   ) {}    \/* istanbul ignore next *\/   public get id() {     return this._id;   }    \/* istanbul ignore next *\/   public get name() {     return this._name;   }    \/* istanbul ignore next *\/   public get price() {     return this._price;   } } <\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043b\u0438\u0441\u0442\u0438\u043d\u0433 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u0432:<\/p>\n<pre><code class=\"javascript\">import { ProductEntity } from \".\/ProductEntity\";  export class ProductListEntity {   constructor(protected readonly _products: ProductEntity[] = []) {}    \/* istanbul ignore next *\/   get products() {     return this._products;   }    get namesLog() {     return this._products.map((product) => product.name).join(\" \");   } } <\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043c\u0435\u0442\u043e\u0434\u044b \u0438\u043b\u0438 \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u0433\u0435\u0442\u0442\u0435\u0440\u044b \u0438 \u0441\u0435\u0442\u0442\u0435\u0440\u044b, \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u044e \u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0435\u0441\u0442\u044b:<\/p>\n<pre><code class=\"javascript\">import { ProductListingMock } from \"..\/..\/..\/application\/mocks\/ProductListingMock\";  describe(\"Testing ProductListEntity\", () => {   test(\"get namesLog\", () => {     expect(ProductListingMock.namesLog === \"snickers mars kinder\").toBeTruthy();   }); }); <\/code><\/pre>\n<p>\u043f\u0440\u0438\u043c\u0435\u0440 \u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439.<\/p>\n<p>\u0414\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043c\u043e\u043a\u0438. \u0422\u0430\u043a\u0436\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u0434\u043b\u044f \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438, \u0438\u043b\u0438 \u0432 \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u044b\u0445 \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u0430\u0445, \u043f\u043e\u043a\u0430 \u0433\u043e\u0442\u043e\u0432\u044f\u0442\u0441\u044f \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0430 \u0431\u044d\u043a\u0435\u043d\u0434\u0435.<\/p>\n<pre><code class=\"javascript\">import { ProductListEntity } from \"..\/..\/domain\/product\/ProductListEntity\"; import { ProductEntity } from \"..\/..\/domain\/product\/ProductEntity\";  export const ProductListingMock = new ProductListEntity([   new ProductEntity(\"1\", \"snickers\", 60),   new ProductEntity(\"2\", \"mars\", 80),   new ProductEntity(\"3\", \"kinder\", 120), ]); <\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u043e\u0433\u043e \u043f\u043e\u0440\u0442\u0430 ProductLoadPort \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437\u0432\u043d\u0435:<\/p>\n<pre><code class=\"javascript\">import { Either } from \"@sweet-monads\/either\"; import { ErrorEntity } from \"..\/ErrorEntity\"; import { ProductListEntity } from \".\/ProductListEntity\"; import { ProductLoadCommand } from \".\/ProductLoadCommand\"; export interface ProductLoadPort {   load(command: ProductLoadCommand): Either&lt;ErrorEntity, ProductListEntity>; }<\/code><\/pre>\n<p>\u041d\u0430 \u0432\u0445\u043e\u0434 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 ProductLoadCommand \u0438 \u043e\u0442\u0434\u0430\u0435\u043c ProductListEnitity \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0443\u0441\u043f\u0435\u0445\u0430 \u0438\u043b\u0438 ErrorEntities \u043f\u0440\u0438 \u043e\u0448\u0438\u0431\u043a\u0435.<\/p>\n<p>ProductLoadCommand:<\/p>\n<pre><code class=\"javascript\">import { ProductId } from \".\/ProductEntity\";  export class ProductLoadCommand {   constructor(     private readonly _ids: ProductId[],     private readonly _lang: string = \"ru\"   ) {}    public get ids(): ProductId[] {     return this._ids;   }    public get lang(): ProductId {     return this._lang;   } } <\/code><\/pre>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u044d\u0442\u043e\u0442 \u043f\u043e\u0440\u0442 \u0432 \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u043e\u043c \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u0435:<\/p>\n<pre><code class=\"javascript\">import { ProductLoadPort } from \"..\/..\/..\/domain\/product\/ProductLoadPort\"; import { ProductLoadCommand } from \"..\/..\/..\/domain\/product\/ProductLoadCommand\"; import { productsMapper } from \"..\/..\/mappers\/ProductMapper\"; import { ProductsResponseSchema } from \"..\/..\/schema\/ProductsSchema\"; import { right, left } from \"@sweet-monads\/either\"; import { ErrorEntity } from \"..\/..\/..\/domain\/ErrorEntity\"; import { AxiosType } from \"..\/..\/..\/types\/AxiosType\";  export class ProductLoadAdapter implements ProductLoadPort {   api(command: ProductLoadCommand): AxiosType {     const responseJson = process.api.products.filter((product) => {       return command.ids.includes(product.id);     });     return {       data: responseJson as unknown,       code: 200,     };   }    load(command: ProductLoadCommand) {     const response = this.api(command);     const valid = ProductsResponseSchema.safeParse(response.data);     return valid.success       ? right(productsMapper(valid.data))       : left(new ErrorEntity(\"productLoad\", valid.error));   } } <\/code><\/pre>\n<p>\u041c\u0435\u0442\u043e\u0434 api \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0435 \u0434\u043b\u044f \u043d\u0430\u0441 \u0434\u0430\u043d\u043d\u044b\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443\u00a0 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0430\u043b\u0438\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u043f\u043e \u0441\u0445\u0435\u043c\u0435:<\/p>\n<p>ProductsResponseSchema<\/p>\n<pre><code class=\"javascript\">import { z } from \"zod\";  export const ProductsResponseSchema = z.array(   z.object({     id: z.string().max(2),     title: z.string(),     price: z.number().max(1000),   }) ); export type ProductsResponseSchemaType = z.infer&lt;typeof ProductsResponseSchema>; <\/code><\/pre>\n<pre><code class=\"javascript\"> const valid = ProductsResponseSchema.safeParse(response.data);<\/code><\/pre>\n<p>\u0435\u0441\u043b\u0438 valid.success = true,\u00a0 \u0432\u044b\u0437\u043e\u0432\u0435\u043c DTO (mapper)\u00a0<\/p>\n<p>productMapper:<\/p>\n<pre><code class=\"javascript\">import { ProductEntity } from \"..\/..\/domain\/product\/ProductEntity\"; import { ProductListEntity } from \"..\/..\/domain\/product\/ProductListEntity\"; import { ProductsResponseSchemaType } from \"..\/schema\/ProductsSchema\";  export function productsMapper(   response: ProductsResponseSchemaType ): ProductListEntity {   return new ProductListEntity(     response.map(       (product) => new ProductEntity(product.id, product.title, product.price)     )   ); }<\/code><\/pre>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u043c\u044b \u0443\u0436\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043b\u0438, \u0447\u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u043c\u0435\u0442\u043e\u0434\u0430 api \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0442\u0438\u043f\u0443 ProductsResponseSchemaType (valid.success = true),<\/p>\n<p>\u0432 productMapper \u043e\u0448\u0438\u0431\u043e\u043a \u043d\u0435 \u0431\u0443\u0434\u0435\u0442.<\/p>\n<p>\u0412 productMapper \u043b\u0438\u0448\u044c \u043e\u0434\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435, \u043f\u043e\u043b\u0435 title \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0432 name.<\/p>\n<p>\u041f\u0435\u0440\u0432\u0438\u0447\u043d\u044b\u0439 \u0430\u0434\u0430\u043f\u0442\u0435\u0440 \u0433\u043e\u0442\u043e\u0432!<\/p>\n<p>\u041f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u0432\u0442\u043e\u0440\u0438\u0447\u043d\u043e\u043c\u0443 \u043f\u043e\u0440\u0442\u0443, \u0433\u0434\u0435 \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0443\u0444\u0444\u0438\u043a\u0441\u044b Query \u0434\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0438 UseCase \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439.<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043f\u043e\u0440\u0442\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0432\u0442\u043e\u0440\u0438\u0447\u043d\u044b\u0439 \u0430\u0434\u0430\u043f\u0442\u0435\u0440 (\u0441\u0435\u0440\u0432\u0438\u0441):<\/p>\n<pre><code class=\"javascript\">import { ProductLoadQuery } from \"..\/..\/..\/domain\/product\/ProductLoadQuery\"; import { ProductLoadCommand } from \"..\/..\/..\/domain\/product\/ProductLoadCommand\"; import { ProductLoadAdapter } from \"..\/..\/adapters\/product\/ProductLoad\"; import { ProductId } from \"..\/..\/..\/domain\/product\/ProductEntity\";  export class ProductLoadService implements ProductLoadQuery {   productLoadPort = new ProductLoadAdapter();    localization() {     \/\/ mock browser api     const navigator = {       language: \"en-EN\",     };     const userLang = navigator.language;     switch (userLang) {       case \"ru-RU\":         return \"ru\";       case \"en-EN\":         return \"en\";       default:         return \"ru\";     }   }    load(ids: ProductId[]) {     const command = new ProductLoadCommand(ids, this.localization());     return this.productLoadPort.load(command);   } } <\/code><\/pre>\n<p>\u0412\u043e \u0432\u0442\u043e\u0440\u0438\u0447\u043d\u043e\u043c \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043d\u043e\u0435 api, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043b\u043e\u043a\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u044b.<\/p>\n<p>\u041a\u0430\u043a \u0432\u0438\u0434\u043d\u043e, \u0432\u0442\u043e\u0440\u0438\u0447\u043d\u044b\u0439 \u0430\u0434\u0430\u043f\u0442\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0432\u044b\u0437\u043e\u0432 \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u043e\u0433\u043e \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u0430 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p>\u041d\u0430\u043f\u0440\u043e\u0442\u0438\u0432, \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u044b\u0439 \u0430\u0434\u0430\u043f\u0442\u0435\u0440 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u043f\u0440\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043b\u0430\u0441\u0441\u0430 \u0432\u0442\u043e\u0440\u0438\u0447\u043d\u043e\u0433\u043e \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u0430 (service).\u042d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u043a\u043b\u0430\u0441\u0441 \u0447\u0438\u0441\u0442\u044b\u043c. \u0412 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0432 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u00a0 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u043a\u0438\u0434\u044b\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u044b\u0439 \u0430\u0434\u0430\u043f\u0442\u0435\u0440 \u0432\u043e \u0432\u0442\u043e\u0440\u0438\u0447\u043d\u044b\u0439. \u041a\u0430\u0436\u0434\u044b\u0439 \u0432\u043e\u043b\u0435\u043d \u0432\u044b\u0431\u0438\u0440\u0430\u0442\u044c \u0443\u0434\u043e\u0431\u043d\u0443\u044e \u0434\u043b\u044f \u043d\u0435\u0433\u043e \u0441\u0445\u0435\u043c\u0443.<\/p>\n<hr\/>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>\u0414\u0430\u043d\u043d<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\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-330381","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/330381","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=330381"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/330381\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=330381"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=330381"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=330381"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}