рдорд╛рдЗрдХреНрд░реЛрд╕реЙрд░реНрдлрд╝ рдмреНрд▓реЙрдЧ рд▓рд┐рдЦрдирд╛ - рднрд╛рдЧ 1 "рд╕рд╛рдорд╛рдиреНрдп рд╡рд┐рд╡рд░рдг"

рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдореИрдВ рдЕрдкрдирд╛ рдЕрдиреБрднрд╡ рд╕рд░реНрдЧреЗрд╕рдорд╛рд╕рд▓реЛрд╡ рдХреЗ рд╕рд╛рде "рд╕реЗ рдПрдХ рдмреНрд▓реЙрдЧ рдмрдирд╛рдиреЗ" рдХрд╛рд░реНрдп рдХреЗ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдорд╛рдЗрдХреНрд░реЛрд╕рд┐рд╕реНрдЯрд╡рд░реНрдХ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╕реБрд▓рдЭрд╛рдиреЗ рдХреЗ рд╕рд╛рде рд╕рд╛рдЭрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ (рдЗрд╕ рдЙрдореНрдореАрдж рдореЗрдВ рдХрд┐ рдкрд╛рдардХ рдХрд▓реНрдкрдирд╛ рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдмреНрд▓реЙрдЧ рдХреИрд╕реЗ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдкрд░ рд╕рд╡рд╛рд▓ рдирд╣реАрдВ рдЙрдард╛рдирд╛ рдЪрд╛рд╣рд┐рдП :)

рддреЛ, рд╣рдорд╛рд░реЗ рдмреНрд▓реЙрдЧ рдореЗрдВ 5 microservices рд╢рд╛рдорд┐рд▓ рд╣реЛрдВрдЧреЗ рдЬреЛ рдЧреЛрд▓рдВрдЧ рдореЗрдВ рд▓рд┐рдЦреЗ рдЧрдП рд╣реИрдВ:

  • рдЧреЗрдЯрд╡реЗ рдПрдкреАрдЖрдИ (рдПрдкреА-рдЬреАрдбрдмреНрд▓реНрдпреВ) - рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рдорд╛рд░реНрдЧ, рдкреНрд░рдорд╛рдгреАрдХрд░рдг, рд▓реЙрдЧрд┐рдВрдЧ рдФрд░ рдЕрдиреБрд░реЗрдЦрдг рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░
  • рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ (рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛) - рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХрд╛ рдкрдВрдЬреАрдХрд░рдг / рдкреНрд░рдорд╛рдгреАрдХрд░рдг, рд▓реЙрдЧрд┐рдВрдЧ, рдЕрдиреБрд░реЛрдзреЛрдВ рдХрд╛ рдЕрдиреБрд░реЗрдЦрдг
  • рд▓реЗрдЦ (рдкреЛрд╕реНрдЯ) - рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рд▓реЗрдЦ (рд╕реАрдЖрд░рдпреВрдбреА), рд▓реЙрдЧрд┐рдВрдЧ, рдЯреНрд░реЗрд╕рд┐рдВрдЧ рдФрд░ рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдмрдирд╛рдирд╛ / рдкрдврд╝рдирд╛ / рд╕рдВрд╢реЛрдзрд┐рдд / рд╣рдЯрд╛рдирд╛
  • рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдВ (рдЯрд┐рдкреНрдкрдгреА) - рдЕрдиреБрд░реЛрдзреЛрдВ (рд▓реЙрдЧрд┐рдВрдЧ, рдЯреНрд░реЗрд╕рд┐рдВрдЧ рдФрд░ рдкреНрд░рд╛рдзрд┐рдХрд░рдг) рдХреА рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ (CRUD) рдХреЛ рдмрдирд╛рдПрдВ / рдкрдврд╝реЗрдВ / рд╕рдВрд╢реЛрдзрд┐рдд / рд╣рдЯрд╛рдПрдВ
  • рд╢реНрд░реЗрдгрд┐рдпрд╛рдВ (рд╢реНрд░реЗрдгреА) - рдЕрдиреБрд░реЛрдзреЛрдВ рдХреА рд╢реНрд░реЗрдгреА рдмрдирд╛рдирд╛ (рдкрдврд╝рдирд╛ / рдмрджрд▓рдирд╛ / рд╣рдЯрд╛рдирд╛ / рд╣рдЯрд╛рдирд╛), рд▓реЙрдЧрд┐рдВрдЧ, рдЕрдиреБрд░реЗрдЦрдг рдФрд░ рдкреНрд░рд╛рдзрд┐рдХрд░рдг

рдХреНрд▓рд╛рдЗрдВрдЯ рдПрдкреНрд▓рд┐рдХреЗрд╢рди (рд╡реЗрдм тАЛтАЛ/ рдлреНрд░рдВрдЯрдПрдВрдб) vue.js рдкрд░ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдЖрд░рдИрдПрд╕рдЯреА рдПрдкреАрдЖрдИ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдорд╛рдЗрдХреНрд░реЛрд╕рд░реНрд╡рд┐рд╕реЗрдЬ рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХрд░реЗрдЧрд╛, рдФрд░ рд╕реНрд╡рдпрдВ рдорд╛рдЗрдХреНрд░реЛрд╕реЙрд░реНрдХреНрд╕ рдЬреАрдЖрд░рдкреАрд╕реА рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдХ-рджреВрд╕рд░реЗ рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХрд░реЗрдВрдЧреЗред

рднрдВрдбрд╛рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ рд╣рдо MongoDB рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред

рд╣рдо рдХреЗрдХ рдкрд░ рдПрдХ рдЕрд▓рдЧ рдЪреЗрд░реА рдХреЗ рд╕рд╛рде рджрд┐рдЦрд╛рдПрдВрдЧреЗ рдХрд┐ рдиреНрдпреВрдирддрдо рд╢реНрд░рдо рдХреЗ рд╕рд╛рде рд╕рдХреНрд░рд┐рдп рд░реВрдк рд╕реЗ рд╡рд┐рдХрд╕рд┐рдд рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдПрдкреАрдЖрдИ рдкреНрд░рд▓реЗрдЦрди (рд╕реНрд╡реИрдЧрд░ рдкреНрд░рд╛рд░реВрдк рдореЗрдВ) рдХреЛ рдЕрдк-рдЯреВ-рдбреЗрдЯ рдХреИрд╕реЗ рд░рдЦрд╛ рдЬрд╛рдПред

рдмреНрд▓реЙрдЧ рдШрдЯрдХ рдЖрд░реЗрдЦ


рдЫрд╡рд┐

рдкреНрд░рддреНрдпреЗрдХ рдорд╛рдЗрдХреНрд░реЛ рд╕рд░реНрд╡рд┐рд╕ рдХреЛ рдПрдХ рдЕрд▓рдЧ рдбреЙрдХрдЯрд░ рдХрдВрдЯреЗрдирд░ рдореЗрдВ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдФрд░ рдбреЙрдХрдЯрд░-рдХрдВрдкреЛрдЬрд╝ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд▓реЙрдиреНрдЪ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рддреБрд░рдВрдд рдЖрд░рдХреНрд╖рдг рдХрд░реЗрдВ, рд╡рд┐рдХрд╛рд╕ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рд╕рд░рд▓ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВ рджреЛ рдорд╛рдиреНрдпрддрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реВрдВрдЧрд╛ рдЬрд┐рдирдХрд╛ рдЙрддреНрдкрд╛рджрди рдореЗрдВ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

  • рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рдбреЙрдХрдЯрд░ рдХрдВрдЯреЗрдирд░ рдореЗрдВ рддреИрдирд╛рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рднрдВрдбрд╛рд░рдг рд╡рд┐рд╢реНрд╡рд╕рдиреАрдпрддрд╛ рдХреЛ рдХрдо рдХрд░рддрд╛ рд╣реИ (рд╣рд╛рдИрд▓рд╛рдб 2018 рдореЗрдВ рдЪрд░реНрдЪрд╛ рдХреА рдЧрдИ рдпреЛрдЬрдирд╛ рдХреЗ рдЕрдкрд╡рд╛рдж рдХреЗ рд╕рд╛рде)ред
  • рдкреВрд░реЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЛ рдПрдХ рдЧрд┐рдЯ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рд╣реЛрд╕реНрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдорд╛рдЗрдХреНрд░реЛрд╕рд░реНрд╡рд┐рд╕ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ - рдЕрд▓рдЧрд╛рд╡ рдХреЗ рдмреБрдирд┐рдпрд╛рджреА рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХрд╛ рдЦрдВрдбрди рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЕрдВрддрд░-рдШрдЯрдХ рдХрдиреЗрдХреНрдЯрд┐рд╡рд┐рдЯреА рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдХреЛ рдмрдврд╝рд╛рддрд╛ рд╣реИред

рдЖрдк рдпрд╣рд╛рдВ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХрд╛ рдбреЗрдореЛ рдФрд░ рд╕реЛрд░реНрд╕ рдХреЛрдб рдпрд╣рд╛рдВ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВред

рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреА рд╕рдВрд░рдЪрдирд╛




рд╡рд┐рдХрд╛рд╕ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХреИрд╕реЗ рд╣реЛрдЧрд╛


рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВрдиреЗ рдкрд╣рд▓реЗ рдХрд╣рд╛ рдерд╛, рдорд╛рдЗрдХреНрд░реЛрд╕рд░реНрд╡рд┐рд╕реЗрдЬ рдХреЗ рдмреАрдЪ рдмрд╛рддрдЪреАрдд рдЬреАрдЖрд░рдкреАрд╕реА рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реЛрдЧреАред рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ, рдЬреАрдЖрд░рдкреАрд╕реА рдПрдХ рдЙрдЪреНрдЪ рдкреНрд░рджрд░реНрд╢рди рд╡рд╛рд▓реА рд░реВрдкрд░реЗрдЦрд╛ рд╣реИ рдЬрд┐рд╕реЗ рджреВрд░рд╕реНрде рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ (рдЖрд░рдкреАрд╕реА) рдХреЗ рд▓рд┐рдП Google рджреНрд╡рд╛рд░рд╛ рд╡рд┐рдХрд╕рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ - рдпрд╣ HTTP / 2 рдХреЗ рд╢реАрд░реНрд╖ рдкрд░ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдЬреАрдЖрд░рдкреАрд╕реА рддрдерд╛рдХрдерд┐рдд рдкреНрд░реЛрдЯреЛрдлрд╛рдЗрд▓ (рдиреАрдЪреЗ рдЙрджрд╛рд╣рд░рдг рджреЗрдЦреЗрдВ) рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдореБрдЦреНрдп рдХрд╛рд░реНрдп рджреЛ рдЪреАрдЬреЛрдВ рдХреЛ рдХреЙрдореНрдкреИрдХреНрдЯ рд░реВрдк рдореЗрдВ рдШреЛрд╖рд┐рдд рдХрд░рдирд╛ рд╣реИ:

  • рд╕реЗрд╡рд╛ рдЗрдВрдЯрд░рдлреЗрд╕ (рдПрдкреАрдЖрдИ рдЗрдВрдЯрд░рдлреЗрд╕ рдХрд╛ рдПрдирд╛рд▓реЙрдЧ) рдХреА рдкреВрд░реА рд╕реВрдЪреА рджреЗрдВ;
  • рд╡рд░реНрдгрди рдХрд░реЗрдВ рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рдЗрдирдкреБрдЯ рдХреЛ рдХреНрдпрд╛ рдЦрд┐рд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЖрдЙрдЯрдкреБрдЯ рдкрд░ рд╣рдореЗрдВ рдХреНрдпрд╛ рдорд┐рд▓рддрд╛ рд╣реИред

рдиреАрдЪреЗ, рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ, рд╢реНрд░реЗрдгреА рд╕реЗрд╡рд╛ рдХрд╛ рдкреНрд░реЛрдЯреЛрдлрд╛рдЗрд▓ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

syntax = "proto3"; package protobuf; import "google/api/annotations.proto"; //   Category service CategoryService { //  rpc Create (CreateCategoryRequest) returns (CreateCategoryResponse) { option (google.api.http) = { post: "/api/v1/category" }; } //  rpc Update (UpdateCategoryRequest) returns (UpdateCategoryResponse) { option (google.api.http) = { post: "/api/v1/category/{Slug}" }; } //  rpc Delete (DeleteCategoryRequest) returns (DeleteCategoryResponse) { option (google.api.http) = { delete: "/api/v1/category/{Slug}" }; } //   SLUG rpc Get (GetCategoryRequest) returns (GetCategoryResponse) { option (google.api.http) = { get: "/api/v1/category/{Slug}" }; } // rpc Find (FindCategoryRequest) returns (FindCategoryResponse) { option (google.api.http) = { get: "/api/v1/category" }; } } //------------------------------------------ // CREATE //------------------------------------------ message CreateCategoryRequest { string ParentId = 1; string Name = 2; string Path = 3; } message CreateCategoryResponse { Category Category = 1; } //------------------------------------------ // UPDATE //------------------------------------------ message UpdateCategoryRequest { string Slug = 1; string ParentId = 2; string Name = 4; string Path = 5; int32 Status = 6; } message UpdateCategoryResponse { int32 Status =1; } //------------------------------------------ // DELETE //------------------------------------------ message DeleteCategoryRequest { string Slug = 1; } message DeleteCategoryResponse { int32 Status =1; } //------------------------------------------ // GET //------------------------------------------ message GetCategoryRequest { string Slug = 1; } message GetCategoryResponse { Category Category = 1; } //------------------------------------------ // FIND //------------------------------------------ message FindCategoryRequest { string Slug = 1; } message FindCategoryResponse { repeated Category Categories = 1; } //------------------------------------------ // CATEGORY //------------------------------------------ message Category { string Slug = 1; string ParentId = 2; string Path = 3; string Name = 4; int32 Status = 5; } 

рдЕрдм рдЬрдм рд╣рдо рд╕рд╛рдорд╛рдиреНрдп рд╢рдмреНрджреЛрдВ рдореЗрдВ рд╕рдордЭ рдЧрдП рд╣реИрдВ рдХрд┐ рдПрдХ рдкреНрд░реЛрдЯреЛрдлрд╛рдЗрд▓ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рд╣реИ, рддреЛ рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдорд╛рдЗрдХреНрд░реЛрд╕рд░реНрд╡рд┐рд╕ рдХреА рд╡рд┐рдХрд╛рд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреИрд╕реЗ рджрд┐рдЦрд╛рдИ рджреЗрдЧреА:

  1. рд╣рдо рдкреНрд░реЛрдЯреЛрдлрд╛рдЗрд▓ рдореЗрдВ рд╕реЗрд╡рд╛ рдХреА рд╕рдВрд░рдЪрдирд╛ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реИрдВ;
  2. рд╣рдо рдХреЛрдб рдЬрдирд░реЗрдЯрд░ ((./bin/protogen.sh) рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ, рдпрд╣ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рд╕рд░реНрд╡рд░ рдХреЛрдб рдХрд╛ рдореБрдЦреНрдп рднрд╛рдЧ рдЙрддреНрдкрдиреНрди рдХрд░реЗрдЧрд╛ + рдпрд╣ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛрдб рдмрдирд╛рдПрдЧрд╛, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдкреАрдЖрдИ рдЧреЗрдЯрд╡реЗ + рдХреЗ рд▓рд┐рдП рдпрд╣ рд╕реНрд╡реИрдЧрд░ рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рдЕрдк-рдЯреВ-рдбреЗрдЯ рдкреНрд░рд▓реЗрдЦрди рдмрдирд╛рдПрдЧрд╛;
  3. рд╣рдо рд╕рднреА рдХреЛ рдЕрдкрдиреЗ рд╣рд╛рдереЛрдВ рд╕реЗ рдХрд░рдирд╛ рд╣реИ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдлрд╝рд╛рдЗрд▓ /protobuf/functions.go рдореЗрдВ рдЗрдВрдЯрд░рдлреЗрд╕ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП рдХреЛрдб рд▓рд┐рдЦрдирд╛ рд╣реИред

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрджрд┐ рд╣рдо рдЕрдкрдиреЗ рдХрд┐рд╕реА рдорд╛рдЗрдХреНрд░реЛрд╕реЙрдлрд╝реНрдЯ рдореЗрдВ рдмрджрд▓рд╛рд╡ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдЙрдкрд░реЛрдХреНрдд рдПрд▓реНрдЧреЛрд░рд┐рдердо рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВ: рд╣рдо рдкреНрд░реЛрдЯреЙрдлрд╝рд╛рдЗрд▓ рдХреЛ рд╕рдВрдкрд╛рджрд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдкреНрд░реЛрдЯреЛрдЬреЗрди рдЪрд▓рд╛рддреЗ рд╣реИрдВ, рд╣рдо рдлрд╝рдВрдХреНрд╢рдВрд╕ рдореЗрдВ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕рдВрдкрд╛рджрд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, рдФрд░ рдкрд░рд┐рд╡рд░реНрддрди рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реЛрдВ рдФрд░ рдХреНрд▓рд╛рдЗрдВрдЯреНрд╕ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ "рдЫреЛрдбрд╝" рджреЗрдВрдЧреЗред

рд▓реЗрдЦ рдореЗрдВ рдЬрд╛рд░реА рд░рдЦрд╛ рдЧрдпрд╛ "рдЧреЗрдЯрд╡реЗ рдПрдкреАрдЖрдИ рдХреЗ рдорд╛рдЗрдХреНрд░реЛрд╕рд░реНрд╡рд┐рд╕ рдкрд╛рд░реНрдЯ 2 рдкрд░ рдПрдХ рдмреНрд▓реЙрдЧ рд▓рд┐рдЦрдирд╛ ред "

Source: https://habr.com/ru/post/hi473514/


All Articles