рд╕реНрд╡-рджрд╕реНрддрд╛рд╡реЗрдЬреАрдХрд░рдг рдмрд╛рдХреА рд╕рд░реНрд╡рд░ (Node.JS, рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ, Koa, рдЬреЛрдИ, рд╕реНрд╡реИрдЧрд░)


рдмрд╣реБрдд рд╕рд╛рд░реЗ рд▓реЗрдЦ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА REST рдХреЗ рдлрд╛рдпрджреЗ рдФрд░ рдиреБрдХрд╕рд╛рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд▓рд┐рдЦреЗ рдЧрдП рд╣реИрдВ (рдФрд░ рдЙрдиреНрд╣реЗрдВ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рдФрд░ рднреА рдЕрдзрд┐рдХ)ред рдФрд░ рдЕрдЧрд░ рдРрд╕рд╛ рд╣реБрдЖ рд╣реИ рдХрд┐ рдЖрдкрдХреЛ рдПрдХ рд╕реЗрд╡рд╛ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдиреА рд╣реЛрдЧреА рдЬрд┐рд╕рдореЗрдВ рдпрд╣ рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рд▓рд╛рдЧреВ рдХреА рдЬрд╛рдиреА рдЪрд╛рд╣рд┐рдП, рддреЛ рдЖрдк рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЗрд╕рдХреЗ рдкреНрд░рд▓реЗрдЦрди рдореЗрдВ рдЖрдПрдВрдЧреЗред рдЖрдЦрд┐рд░рдХрд╛рд░, рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рдзрд┐ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рддреЗ рд╣реБрдП, рд╣рдо рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рд╕рдордЭрддреЗ рд╣реИрдВ рдХрд┐ рдЕрдиреНрдп рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдЗрди рддрд░реАрдХреЛрдВ рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд░реЗрдВрдЧреЗред рдЗрд╕рд▓рд┐рдП, рдкреНрд░рд▓реЗрдЦрди рд╡реНрдпрд╛рдкрдХ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд╛рдд - рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХред

рдмрд┐рд▓реНрд▓реА рдореЗрдВ рдЖрдкрдХрд╛ рд╕реНрд╡рд╛рдЧрдд рд╣реИ, рдЬрд╣рд╛рдВ рдореИрдВ рд╡рд░реНрдгрди рдХрд░реВрдВрдЧрд╛ рдХрд┐ рд╣рдордиреЗ рдЕрдкрдиреА рдЯреАрдо рдореЗрдВ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рдХреИрд╕реЗ рд╣рд▓ рдХрд┐рдпрд╛ред

рдереЛрдбрд╝рд╛ рд╕рд╛ рд╕рдВрджрд░реНрднред

рд╣рдорд╛рд░реА рдЯреАрдо рдХреЛ рдереЛрдбрд╝реЗ рд╕рдордп рдореЗрдВ рдордзреНрдпрдо рдЬрдЯрд┐рд▓рддрд╛ рдХреЗ Node.js рдкрд░ рдПрдХ рдмреИрдХреЗрдВрдб рдЙрддреНрдкрд╛рдж рдЬрд╛рд░реА рдХрд░рдиреЗ рдХрд╛ рдХрд╛рдо рд╕реМрдВрдкрд╛ рдЧрдпрд╛ рдерд╛ред рдлреНрд░рдВрдЯреЗрдВрдб рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдФрд░ рдореЛрдмрд┐рд▓рд╛рдЗрдЬрд░реНрд╕ рдЗрд╕ рдЙрддреНрдкрд╛рдж рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдереЗред

рдХреБрдЫ рд╡рд┐рдЪрд╛рд░ рдХреЗ рдмрд╛рдж, рд╣рдордиреЗ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рд╣рд╛рдВ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ред рд╕реБрд╡реНрдпрд╡рд╕реНрдерд┐рдд TSLint рдФрд░ Prettier рдиреЗ рд╣рдореЗрдВ рдХреЛрдбрд┐рдВрдЧ / рдЕрд╕реЗрдВрдмрд▓реА рд╕реНрдЯреЗрдЬ (рдФрд░ рдХрдорд┐рдЯ рд╕реНрдЯреЗрдЬ рдкрд░ рднреА рд╣рд╕реНрдХреА) рдореЗрдВ рд╕рдорд╛рди рдХреЛрдб рд╕реНрдЯрд╛рдЗрд▓ рдФрд░ рдЯрд╛рдЗрдЯ рдЪреЗрдХ рд╣рд╛рд╕рд┐рд▓ рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХреАред рдордЬрдмреВрдд рдЯрд╛рдЗрдкрд┐рдВрдЧ рдиреЗ рд╕рднреА рдХреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╕рднреА рд╡рд╕реНрддреБрдУрдВ рдХреЗ рдЗрдВрдЯрд░рдлреЗрд╕ рдФрд░ рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░реЗрд░рд┐рдд рдХрд┐рдпрд╛ред рдпрд╣ рдкрдврд╝рдирд╛ рдФрд░ рд╕рдордЭрдирд╛ рдЖрд╕рд╛рди рд╣реЛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдлрд╝рдВрдХреНрд╢рди рдЗрдирдкреБрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреНрдпрд╛ рд▓реЗрддрд╛ рд╣реИ, рдпрд╣ рдЕрдВрддрддрдГ рдХреНрдпрд╛ рд▓реМрдЯреЗрдЧрд╛, рдФрд░ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рдХреМрди рд╕реЗ рдЧреБрдг рдЕрдирд┐рд╡рд╛рд░реНрдп рд╣реИрдВ рдФрд░ рдЬреЛ рдирд╣реАрдВ рд╣реИрдВред рдХреЛрдб рдЬрд╛рд╡рд╛ рд╕реЗ рдмрд╣реБрдд рдорд┐рд▓рддрд╛ рдЬреБрд▓рддрд╛ рд╣реИ)ред рдФрд░ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдЯрд╛рдЗрдкрдбреЙрдХ рдиреЗ рдкреНрд░рддреНрдпреЗрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдкрдардиреАрдпрддрд╛ рдХреЛ рдЬреЛрдбрд╝рд╛ред

рдЗрд╕ рддрд░рд╣ рдХреЛрдб рджрд┐рдЦрдиреЗ рд▓рдЧрд╛:

/** * Interface of all responses */ export interface IResponseData<T> { nonce: number; code: number; message?: string; data?: T; } /** * Utils helper */ export class TransferObjectUtils { /** * Compose all data to result response package * * @param responseCode - 200 | 400 | 500 * @param message - any info text message * @param data - response data object * * @return ready object for REST response */ public static createResponseObject<T = object>(responseCode: number, message: string, data: T): IResponseData<T> { const result: IResponseData<T> = { code: responseCode || 200, nonce: Date.now() }; if (message) { result.message = message; } if (data) { result.data = data; } return result; } } 

рд╣рдордиреЗ рд╡рдВрд╢рдЬреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрд╛, рд╣рдорд╛рд░реЗ рдХреЛрдб рдХреЛ рдмрдирд╛рдП рд░рдЦрдирд╛ рдореБрд╢реНрдХрд┐рд▓ рдирд╣реАрдВ рд╣реЛрдЧрд╛, рдпрд╣ рд╣рдорд╛рд░реЗ REST рд╕рд░реНрд╡рд░ рдХреЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрдиреЗ рдХрд╛ рд╕рдордп рд╣реИред

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

рдпрд╣рд╛рдБ рдореИрдВрдиреЗ рдЗрд╕рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рдЙрдкрдХрд░рдгреЛрдВ рдХреА рдЦреЛрдЬ рдореЗрдВ рджреЗрд░реА рдХреАред рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рдПрдирдкреАрдПрдо рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рд╡рд┐рдЪрд╛рд░реЛрдВ рдФрд░ рд╕рдорд╛рдзрд╛рдиреЛрдВ рдХрд╛ рдПрдХ рднрдВрдбрд╛рд░ рд╣реИред

рдЙрдкрдХрд░рдг рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛рдПрдВ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдереАрдВ:

  • рдХреЛрдб рдХреЗ рд╕рд╛рде рдкреНрд░рд▓реЗрдЦрди рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝реЗрд╢рди;
  • рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╕рдорд░реНрдерди;
  • рдЗрдирдХрдорд┐рдВрдЧ / рдЖрдЙрдЯрдЧреЛрдЗрдВрдЧ рдкреИрдХреЗрдЯ рдХреА рдорд╛рдиреНрдпрддрд╛;
  • рд▓рд╛рдЗрд╡ рдФрд░ рд╕рдорд░реНрдерд┐рдд рдкреИрдХреЗрдЬред

рдореБрдЭреЗ рдХрдИ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдкреИрдХреЗрдЬреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рдПрдХ REST рд╕реЗрд╡рд╛ рдкрд░ рд▓рд┐рдЦрдирд╛ рдкрдбрд╝рд╛, рдЬрд┐рдирдореЗрдВ рд╕реЗ рд╕рдмрд╕реЗ рд▓реЛрдХрдкреНрд░рд┐рдп рд╣реИрдВ: tsoa, тАЛтАЛswagger-node-express, express-openapi, swagger-codegenред



рд▓реЗрдХрд┐рди рдХреБрдЫ рдореЗрдВ рдХреБрдЫ рдкреИрдХреЗрдЬ рд╕рддреНрдпрд╛рдкрди рдореЗрдВ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдерд╛, рдФрд░ рдХреБрдЫ рдкреНрд░рд▓реЗрдЦрди рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдХреЛрдб рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдереЗ, рд▓реЗрдХрд┐рди рдЙрдиреНрд╣реЛрдВрдиреЗ рдЖрдЧреЗ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝реЗрд╢рди рдкреНрд░рджрд╛рди рдирд╣реАрдВ рдХрд┐рдпрд╛ред

рдпрд╣ рд╡рд╣ рдЬрдЧрд╣ рд╣реИ рдЬрд╣рд╛рдБ рдореИрдВ рдЬреЙрдп-рдЯреВ-рд╕реНрд╡реИрдЧрд░ рдореЗрдВ рдЖрдпрд╛ рдерд╛ред рдПрдХ рдорд╣рд╛рди рдкреИрдХреЗрдЬ рдЬреЛ рдмрддрд╛рдП рдЧрдП рд╕реНрдХреАрдо рдХреЛ рд╕реНрд╡реИрдЧрд░ рдбреЙрдХреНрдпреВрдореЗрдВрдЯреЗрд╢рди рдореЗрдВ рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╕рдорд░реНрдерди рдХреЗ рд╕рд╛рде рдмрджрд▓ рд╕рдХрддрд╛ рд╣реИред рд╕рднреА рдЖрдЗрдЯрдо рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝реЗрд╢рди рдХреЛ рдЫреЛрдбрд╝рдХрд░ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред рдХреБрдЫ рд╕рдордп рдХреЗ рд▓рд┐рдП рджреМрдбрд╝рддреЗ рд╣реБрдП, рдореБрдЭреЗ рдПрдХ рдЪреАрдиреА рдХрд╛ рдкрд░рд┐рддреНрдпрдХреНрдд рднрдВрдбрд╛рд░ рдорд┐рд▓рд╛, рдЬрд┐рд╕рдиреЗ рдХреЛрдпрд╛ рдврд╛рдВрдЪреЗ рдХреЗ рд╕рд╛рде рдорд┐рд▓рдХрд░ рдЬреЙрдп-рдЯреВ-рд╕реНрд╡реИрдЧрд░ рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ред рдЪреВрдВрдХрд┐ рд╣рдорд╛рд░реА рдЯреАрдо рдореЗрдВ рдХреЛрдЖ рдХреЗ рдЦрд┐рд▓рд╛рдл рдХреЛрдИ рдкреВрд░реНрд╡рд╛рдЧреНрд░рд╣ рдирд╣реАрдВ рдереЗ, рдФрд░ рдПрдХреНрд╕рдкреНрд░реЗрд╕ рдЯреНрд░реЗрдВрдб рдХрд╛ рдЖрдБрдЦ рдмрдВрдж рдХрд░рдХреЗ рдкрд╛рд▓рди рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рдХрд╛рд░рдг рдирд╣реАрдВ рдерд╛, рдЗрд╕рд▓рд┐рдП рд╣рдордиреЗ рдЗрд╕ рдвреЗрд░ рдкрд░ рдЙрддрд╛рд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ред

рдореИрдВрдиреЗ рдЗрд╕ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА, рдлрд┐рдХреНрд╕реНрдб рдмрдЧ рдХреЛ рдХрд╛рдВрдЯрд╛, рдХреБрдЫ рдЪреАрдЬреЛрдВ рдХреЛ рдкреВрд░рд╛ рдХрд┐рдпрд╛, рдФрд░ рдЕрдм рдУрдкрдирд╕реЛрд░реНрд╕ рдХреЛ-рдЬреЛрдИ-рд╕реНрд╡реИрдЧрд░-рдЯреАрдПрд╕ рдореЗрдВ рдореЗрд░рд╛ рдкрд╣рд▓рд╛ рдпреЛрдЧрджрд╛рди рдЬрд╛рд░реА рдХрд┐рдпрд╛ рдЧрдпрд╛ред рд╣рдордиреЗ рдЙрд╕ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЛ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдФрд░ рдЗрд╕рдХреЗ рдмрд╛рдж рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХрдИ рдЕрдиреНрдп рд▓реЛрдЧ рдереЗред рдпрд╣ REST рд╕реЗрд╡рд╛рдУрдВ рдХреЛ рд▓рд┐рдЦрдиреЗ рдФрд░ рдмрдирд╛рдП рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реЛ рдЧрдпрд╛ рд╣реИ, рдФрд░ рдЗрди рд╕реЗрд╡рд╛рдУрдВ рдХреЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рд╕реНрд╡реИрдЧрд░ рдСрдирд▓рд╛рдЗрди рдкреНрд░рд▓реЗрдЦрди рдХреЗ рд▓рд┐рдВрдХ рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдХреБрдЫ рдирд╣реАрдВ рдЪрд╛рд╣рд┐рдПред рдЙрдирдХреЗ рдмрд╛рдж, рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реЛ рдЧрдпрд╛ рдХрд┐ рдЗрд╕ рдкреИрдХреЗрдЬ рдХреЛ рдХрд╣рд╛рдВ рд╡рд┐рдХрд╕рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдЗрд╕рдореЗрдВ рдХрдИ рдФрд░ рд╕реБрдзрд╛рд░ рд╣реБрдП рд╣реИрдВред

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

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

рддреЛ, рд╢реБрд░реБрдЖрдд рдХреЗ рд▓рд┐рдП, рдЗрд╕ рд╕рд╛рдордЧреНрд░реА рдХреЗ рд╕рд╛рде index.ts рдмрдирд╛рдПрдБ:

index.ts
 import * as Koa from "koa"; import { BaseContext } from "koa"; import * as bodyParser from "koa-bodyparser"; import * as Router from "koa-router"; const SERVER_PORT = 3002; (async () => { const app = new Koa(); const router = new Router(); app.use(bodyParser()); router.get("/", (ctx: BaseContext, next: Function) => { console.log("Root loaded!") }); app .use(router.routes()) .use(router.allowedMethods()); app.listen(SERVER_PORT); console.log(`Server listening on http://localhost:${SERVER_PORT} ...`); })(); 



рдЬрдм рдЖрдк рдЗрд╕ рд╕реЗрд╡рд╛ рдХреЛ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдПрдХ REST рд╕рд░реНрд╡рд░ рдЙрдард╛рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдЬреЛ рдЕрдм рддрдХ рдирд╣реАрдВ рдЬрд╛рдирддрд╛ рд╣реИ рдХрд┐ рдХреИрд╕реЗред рдЕрдм рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреА рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдереЛрдбрд╝рд╛ред рдЪреВрдВрдХрд┐ рдореИрдВрдиреЗ рдЬрд╛рд╡рд╛ рд╕реЗ Node.JS рдкрд░ рд╕реНрд╡рд┐рдЪ рдХрд┐рдпрд╛ рдерд╛, рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рдпрд╣рд╛рдВ рд╕рдорд╛рди рдкрд░рддреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рд╕реЗрд╡рд╛ рдмрдирд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреАред

  • рдирд┐рдпрдВрддреНрд░рдХреЛрдВ
  • рд╕реЗрд╡рд╛рдПрдВ
  • рдЦрдЬрд╛рдиреЗ

рдЖрдЗрдП рдХреЛрдЖ-рдЬреЛрдЗ-рд╕реНрд╡реИрдЧрд░-рдЯреАрдПрд╕ рдХреЛ рдЬреЛрдбрд╝рдирд╛ рд╢реБрд░реВ рдХрд░реЗрдВ ред рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд░реВрдк рд╕реЗ рдЗрд╕реЗ рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВред

 npm install koa-joi-swagger-ts --save 

рдЗрд╕рдореЗрдВ тАЬрдХрдВрдЯреНрд░реЛрд▓рд░тАЭ рдлреЛрд▓реНрдбрд░ рдФрд░ тАЬрд╕реНрдХреАрдорд╛тАЭ рдлреЛрд▓реНрдбрд░ рдмрдирд╛рдПрдБред рдХрдВрдЯреНрд░реЛрд▓рд░ рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ, рд╣рдорд╛рд░рд╛ рдкрд╣рд▓рд╛ рдХрдВрдЯреНрд░реЛрд▓рд░ рдмреЗрд╕ рдмрдирд╛рддреЗ рд╣реИрдВ редcontroller.ts :

base.controller.ts
 import { BaseContext } from "koa"; import { controller, description, get, response, summary, tag } from "koa-joi-swagger-ts"; import { ApiInfoResponseSchema } from "./schemas/apiInfo.response.schema"; @controller("/api/v1") export abstract class BaseController { @get("/") @response(200, { $ref: ApiInfoResponseSchema }) @tag("GET") @description("Returns text info about version of API") @summary("Show API index page") public async index(ctx: BaseContext, next: Function): Promise<void> { console.log("GET /api/v1/"); ctx.status = 200; ctx.body = { code: 200, data: { appVersion: "1.0.0", build: "1001", apiVersion: 1, reqHeaders: ctx.request.headers, apiDoc: "/api/v1/swagger.json" } } }; } 


рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдбреЗрдХреЛрд░реЗрдЯрд░ (рдЬрд╛рд╡рд╛ рдореЗрдВ рдПрдиреЛрдЯреЗрд╢рди) рд╕реЗ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╣ рд╡рд░реНрдЧ рдкрде / / рдПрдкреАрдЖрдИ / v1 рдХреЗ рд╕рд╛рде рдЬреБрдбрд╝рд╛ рд╣реЛрдЧрд╛, рдЕрдВрджрд░ рдХреА рд╕рднреА рд╡рд┐рдзрд┐рдпрд╛рдБ рдЗрд╕ рдкрде рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рд╣реЛрдВрдЧреАред

рдЗрд╕ рдкрджреНрдзрддрд┐ рдореЗрдВ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдкреНрд░рд╛рд░реВрдк рдХрд╛ рд╡рд┐рд╡рд░рдг рд╣реИ, рдЬрд┐рд╕реЗ рдлрд╝рд╛рдЗрд▓ "./schemas/apiInfo.response.schema" рдореЗрдВ рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:

apiInfo.response.schema
 import * as Joi from "joi"; import { definition } from "koa-joi-swagger-ts"; import { BaseAPIResponseSchema } from "./baseAPI.response.schema"; @definition("ApiInfo", "Information data about current application and API version") export class ApiInfoResponseSchema extends BaseAPIResponseSchema { public data = Joi.object({ appVersion: Joi.string() .description("Current version of application") .required(), build: Joi.string().description("Current build version of application"), apiVersion: Joi.number() .positive() .description("Version of current REST api") .required(), reqHeaders: Joi.object().description("Request headers"), apiDoc: Joi.string() .description("URL path to swagger document") .required() }).required(); } 


рдЬреЛрдИ рдореЗрдВ рдпреЛрдЬрдирд╛ рдХреЗ рдРрд╕реЗ рд╡рд┐рд╡рд░рдг рдХреА рд╕рдВрднрд╛рд╡рдирд╛рдПрдВ рдмрд╣реБрдд рд╡реНрдпрд╛рдкрдХ рд╣реИрдВ рдФрд░ рдпрд╣рд╛рдВ рдЕрдзрд┐рдХ рд╡рд┐рд╡рд░рдг рдореЗрдВ рд╡рд░реНрдгрд┐рдд рд╣реИрдВ: www.npmjs.com/package/joi-to-swagger

рдФрд░ рдпрд╣рд╛рдБ рд╡рд░реНрдгрд┐рдд рд╡рд░реНрдЧ рдХрд╛ рдкреВрд░реНрд╡рдЬ рд╣реИ (рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣ рд╣рдорд╛рд░реА рд╕реЗрд╡рд╛ рдХреЗ рд╕рднреА рдЙрддреНрддрд░реЛрдВ рдХреЗ рд▓рд┐рдП рдЖрдзрд╛рд░ рд╡рд░реНрдЧ рд╣реИ):

baseAPI.response.schema
 import * as Joi from "joi"; import { definition } from "koa-joi-swagger-ts"; @definition("BaseAPIResponse", "Base response entity with base fields") export class BaseAPIResponseSchema { public code = Joi.number() .required() .strict() .only(200, 400, 500) .example(200) .description("Code of operation result"); public message = Joi.string().description("message will be filled in some causes"); } 


рдЕрдм рдХреЛрдЖ-рдЬреЛрдЗ-рд╕реНрд╡реИрдЧрд░-рдЯреАрдПрд╕ рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рдЗрди рд╕рд░реНрдХрд┐рдЯ рдФрд░ рдХрдВрдЯреНрд░реЛрд▓рд░ рдХреЛ рдкрдВрдЬреАрдХреГрдд рдХрд░реЗрдВред
Index.ts рдХреЗ рдЖрдЧреЗ, рдПрдХ рдЕрдиреНрдп рд░реВрдЯрд┐рдВрдЧ .ts рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдПрдБ:

routing.ts
 import { KJSRouter } from "koa-joi-swagger-ts"; import { BaseController } from "./controllers/base.controller"; import { BaseAPIResponseSchema } from "./controllers/schemas/baseAPI.response.schema"; import { ApiInfoResponseSchema } from "./controllers/schemas/apiInfo.response.schema"; const SERVER_PORT = 3002; export const loadRoutes = () => { const router = new KJSRouter({ swagger: "2.0", info: { version: "1.0.0", title: "simple-rest" }, host: `localhost:${SERVER_PORT}`, basePath: "/api/v1", schemes: ["http"], paths: {}, definitions: {} }); router.loadDefinition(ApiInfoResponseSchema); router.loadDefinition(BaseAPIResponseSchema); router.loadController(BaseController); router.setSwaggerFile("swagger.json"); router.loadSwaggerUI("/api/docs"); return router.getRouter(); }; 


рдпрд╣рд╛рдВ рд╣рдо KJSRouter рдХреНрд▓рд╛рд╕ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рддреЗ рд╣реИрдВ, рдЬреЛ рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ рдПрдХ рдХреЛрдЖ-рд░рд╛рдЙрдЯрд░ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕рдореЗрдВ рдмрд┐рдЪреМрд▓рд┐рдпреЛрдВ рдФрд░ рд╣реИрдВрдбрд▓рд░реНрд╕ рдХреЛ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рд╣реИред

рдЗрд╕рд▓рд┐рдП, index.ts рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд╣рдо рдмрд╕ рдмрджрд▓рддреЗ рд╣реИрдВ

 const router = new Router(); 

рдкрд░

 const router = loadRoutes(); 

рдЦреИрд░, рдЕрдирд╛рд╡рд╢реНрдпрдХ рд╣реИрдВрдбрд▓рд░ рдХреЛ рд╣рдЯрд╛ рджреЗрдВ:

index.ts
 import * as Koa from "koa"; import * as bodyParser from "koa-bodyparser"; import { loadRoutes } from "./routing"; const SERVER_PORT = 3002; (async () => { const app = new Koa(); const router = loadRoutes(); app.use(bodyParser()); app .use(router.routes()) .use(router.allowedMethods()); app.listen(SERVER_PORT); console.log(`Server listening on http://localhost:${SERVER_PORT} ...`); })(); 


рдЬрдм рдЖрдк рдЗрд╕ рд╕реЗрд╡рд╛ рдХреЛ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдорд╛рд░реЗ рд▓рд┐рдП 3 рдорд╛рд░реНрдЧ рдЙрдкрд▓рдмреНрдз рд╣реИрдВ:
1. рдПрдкрд┐ / v1 - рдкреНрд░рд▓реЗрдЦрд┐рдд рдорд╛рд░реНрдЧ
рдЬреЛ рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ:

http: // localhost: 3002 / рдПрдкреАрдЖрдИ / v1
 { code: 200, data: { appVersion: "1.0.0", build: "1001", apiVersion: 1, reqHeaders: { host: "localhost:3002", connection: "keep-alive", cache-control: "max-age=0", upgrade-insecure-requests: "1", user-agent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36", accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3", accept-encoding: "gzip, deflate, br", accept-language: "uk-UA,uk;q=0.9,ru;q=0.8,en-US;q=0.7,en;q=0.6" }, apiDoc: "/api/v1/swagger.json" } } 


рдФрд░ рджреЛ рд╕реЗрд╡рд╛ рдорд╛рд░реНрдЧ:

реи.рдЖрдкрд┐/v1/swagger.json

swagger.json
 { swagger: "2.0", info: { version: "1.0.0", title: "simple-rest" }, host: "localhost:3002", basePath: "/api/v1", schemes: [ "http" ], paths: { /: { get: { tags: [ "GET" ], summary: "Show API index page", description: "Returns text info about version of API", consumes: [ "application/json" ], produces: [ "application/json" ], responses: { 200: { description: "Information data about current application and API version", schema: { type: "object", $ref: "#/definitions/ApiInfo" } } }, security: [ ] } } }, definitions: { BaseAPIResponse: { type: "object", required: [ "code" ], properties: { code: { type: "number", format: "float", enum: [ 200, 400, 500 ], description: "Code of operation result", example: { value: 200 } }, message: { type: "string", description: "message will be filled in some causes" } } }, ApiInfo: { type: "object", required: [ "code", "data" ], properties: { code: { type: "number", format: "float", enum: [ 200, 400, 500 ], description: "Code of operation result", example: { value: 200 } }, message: { type: "string", description: "message will be filled in some causes" }, data: { type: "object", required: [ "appVersion", "apiVersion", "apiDoc" ], properties: { appVersion: { type: "string", description: "Current version of application" }, build: { type: "string", description: "Current build version of application" }, apiVersion: { type: "number", format: "float", minimum: 1, description: "Version of current REST api" }, reqHeaders: { type: "object", properties: { }, description: "Request headers" }, apiDoc: { type: "string", description: "URL path to swagger document" } } } } } } } 


3. "рдПрдкреАрдЖрдИ / рдбреЙрдХреНрд╕

рдпрд╣ рд╕реНрд╡реИрдЧрд░ UI рд╡рд╛рд▓рд╛ рдкреГрд╖реНрда рд╣реИ - рдпрд╣ рд╕реНрд╡реИрдЧрд░ рд╕реНрдХреАрдо рдХрд╛ рдПрдХ рдмрд╣реБрдд рд╣реА рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рджреГрд╢реНрдп рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реЛрдиреЗ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЖрдк рдЕрдиреБрд░реЛрдз рднреА рдЙрддреНрдкрдиреНрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рд╕рд░реНрд╡рд░ рд╕реЗ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЙрддреНрддрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред



рдЗрд╕ UI рдХреЛ swagger.json рдлрд╝рд╛рдЗрд▓ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдпрд╣реА рд╡рдЬрд╣ рд╣реИ рдХрд┐ рдкрд┐рдЫрд▓реЗ рдорд╛рд░реНрдЧ рдХреЛ рд╢рд╛рдорд┐рд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред

рдЦреИрд░, рд╡рд╣рд╛рдБ рд╕рдм рдХреБрдЫ рд▓рдЧрддрд╛ рд╣реИ рдФрд░ рд╕рдм рдХреБрдЫ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди! ...

рд╕рдордп рдХреЗ рд╕рд╛рде, рд╣рдордиреЗ рдкрд░рд┐рдХреНрд░рдорд╛ рдХреА рдХрд┐ рдЗрд╕ рддрд░рд╣ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдХреЛрдб рджреЛрд╣рд░рд╛рд╡ рд╣реИрдВред рдорд╛рдорд▓реЗ рдореЗрдВ рдЬрдм рдирд┐рдпрдВрддреНрд░рдХреЛрдВ рдХреЛ рдПрдХ рд╣реА рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдпрд╣ рдЗрд╕ рд╡рдЬрд╣ рд╕реЗ рдерд╛ рдХрд┐ рдореИрдВрдиреЗ рдмрд╛рдж рдореЗрдВ рдкреИрдХреЗрдЬ рдХреЛ рдЕрдВрддрд┐рдо рд░реВрдк рджрд┐рдпрд╛ рдФрд░ рдирд┐рдпрдВрддреНрд░рдХреЛрдВ рдХреЗ рд▓рд┐рдП "рдЖрд╡рд░рдг" рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдХреЛ рдЬреЛрдбрд╝рд╛ред

рдРрд╕реА рд╕реЗрд╡рд╛ рдХреЗ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред

рдорд╛рди рд▓реЗрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХрдИ рддрд░реАрдХреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ "рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛" рдирд┐рдпрдВрддреНрд░рдХ рд╣реИред

рд╕рднреА рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ
  @get("/") @response(200, { $ref: UsersResponseSchema }) @response(400, { $ref: BaseAPIResponseSchema }) @response(500, { $ref: BaseAPIResponseSchema }) @tag("User") @description("Returns list of all users") @summary("Get all users") public async getAllUsers(ctx: BaseContext): Promise<void> { console.log("GET /api/v1/users"); let message = "Get all users error"; let code = 400; let data = null; try { let serviceResult = await getAllUsers(); if (serviceResult) { data = serviceResult; code = 200; message = null; } } catch (e) { console.log("Error while getting users list"); code = 500; } ctx.status = code; ctx.body = TransferObjectUtils.createResponseObject(code, message, data); }; 


рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░реЗрдВ
  @post("/") @parameter("body", { $ref: UsersRequestSchema }, ENUM_PARAM_IN.body) @response(200, { $ref: BaseAPIResponseSchema }) @response(400, { $ref: BaseAPIResponseSchema }) @response(500, { $ref: BaseAPIResponseSchema }) @tag("User") @description("Update user data") @summary("Update user data") public async updateUser(ctx: BaseContext): Promise<void> { console.log("POST /api/v1/users"); let message = "Update user data error"; let code = 400; let data = null; try { let serviceResult = await updateUser(ctx.request.body.data); if (serviceResult) { code = 200; message = null; } } catch (e) { console.log("Error while updating user"); code = 500; } ctx.status = code; ctx.body = TransferObjectUtils.createResponseObject(code, message, data); }; 


рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдбрд╛рд▓реЗрдВ
  @put("/") @parameter("body", { $ref: UsersRequestSchema }, ENUM_PARAM_IN.body) @response(200, { $ref: BaseAPIResponseSchema }) @response(400, { $ref: BaseAPIResponseSchema }) @response(500, { $ref: BaseAPIResponseSchema }) @tag("User") @description("Insert new user") @summary("Insert new user") public async insertUser(ctx: BaseContext): Promise<void> { console.log("PUT /api/v1/users"); let message = "Insert new user error"; let code = 400; let data = null; try { let serviceResult = await insertUser(ctx.request.body.data); if (serviceResult) { code = 200; message = null; } } catch (e) { console.log("Error while inserting user"); code = 500; } ctx.status = code; ctx.body = TransferObjectUtils.createResponseObject(code, message, data); }; 


рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рддреАрди рдирд┐рдпрдВрддреНрд░рдХ рд╡рд┐рдзрд┐рдпреЛрдВ рдореЗрдВ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рдХреЛрдб рд╣реИред рдпрд╣ рдРрд╕реЗ рдорд╛рдорд▓реЛрдВ рдХреЗ рд▓рд┐рдП рд╣реИ рдЬреЛ рдЕрдм рд╣рдо рдЗрд╕ рдЕрд╡рд╕рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВред

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдПрдХ рд░реИрдкрд░ рдлрд╝рдВрдХреНрд╢рди рдмрдирд╛рдПрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╕реАрдзреЗ рд░рд╛рдЙрдЯрд┐рдВрдЧ рдлрд╝рд╛рдЗрд▓ рдореЗрдВред

 const controllerDecorator = async (controller: Function, ctx: BaseContext, next: Function, summary: string): Promise<void> => { console.log(`${ctx.request.method} ${ctx.request.url}`); ctx.body = null; ctx.status = 400; ctx.statusMessage = `Error while executing '${summary}'`; try { await controller(ctx); } catch (e) { console.log(e, `Error while executing '${summary}'`); ctx.status = 500; } ctx.body = TransferObjectUtils.createResponseObject(ctx.status, ctx.statusMessage, ctx.body); }; 

рдлрд┐рд░ рдЗрд╕реЗ рд╣рдорд╛рд░реЗ рдирд┐рдпрдВрддреНрд░рдХ рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВред

рдХреА рдЬрдЧрд╣

 router.loadController(UserController); 

рдкрд░

 router.loadController(UserController, controllerDecorator); 

рдареАрдХ рд╣реИ, рдЪрд▓реЛ рд╣рдорд╛рд░реЗ рдирд┐рдпрдВрддреНрд░рдХ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рд╕рд░рд▓ рдмрдирд╛рддреЗ рд╣реИрдВ

рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдирд┐рдпрдВрддреНрд░рдХ
  @get("/") @response(200, { $ref: UsersResponseSchema }) @response(400, { $ref: BaseAPIResponseSchema }) @response(500, { $ref: BaseAPIResponseSchema }) @tag("User") @description("Returns list of all users") @summary("Get all users") public async getAllUsers(ctx: BaseContext): Promise<void> { let serviceResult = await getAllUsers(); if (serviceResult) { ctx.body = serviceResult; ctx.status = 200; ctx.statusMessage = null; } }; @post("/") @parameter("body", { $ref: UsersRequestSchema }, ENUM_PARAM_IN.body) @response(200, { $ref: BaseAPIResponseSchema }) @response(400, { $ref: BaseAPIResponseSchema }) @response(500, { $ref: BaseAPIResponseSchema }) @tag("User") @description("Update user data") @summary("Update user data") public async updateUser(ctx: BaseContext): Promise<void> { let serviceResult = await updateUser(ctx.request.body.data); if (serviceResult) { ctx.status = 200; ctx.statusMessage = null; } }; @put("/") @parameter("body", { $ref: UsersRequestSchema }, ENUM_PARAM_IN.body) @response(200, { $ref: BaseAPIResponseSchema }) @response(400, { $ref: BaseAPIResponseSchema }) @response(500, { $ref: BaseAPIResponseSchema }) @tag("User") @description("Insert new user") @summary("Insert new user") public async insertUser(ctx: BaseContext): Promise<void> { let serviceResult = await insertUser(ctx.request.body.data); if (serviceResult) { ctx.status = 200; ctx.statusMessage = null; } }; 


рдЗрд╕ рдХрдВрдЯреНрд░реЛрд▓рд░ рдбреЗрдХреЛрд░реЗрдЯрд░ рдореЗрдВ, рдЖрдк рдЪреЗрдХ рдХреЗ рдХрд┐рд╕реА рднреА рддрд░реНрдХ рдпрд╛ рдЗрдирдкреБрдЯ / рдЖрдЙрдЯрдкреБрдЯ рдХреЗ рд╡рд┐рд╕реНрддреГрдд рд▓реЙрдЧ рдХреЛ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред

рдореИрдВрдиреЗ рдпрд╣рд╛рдВ рддреИрдпрд╛рд░ рдХреЛрдб рдкреЛрд╕реНрдЯ рдХрд┐рдпрд╛ рд╣реИ ред

рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд▓рдЧрднрдЧ CRUD рддреИрдпрд╛рд░ рд╣реИред рд╣рдЯрд╛рдХрд░ рд╕рд╛рджреГрд╢реНрдп рджреНрд╡рд╛рд░рд╛ рд▓рд┐рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдЕрдм рдПрдХ рдирдпрд╛ рдирд┐рдпрдВрддреНрд░рдХ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдЪрд╛рд╣рд┐рдП:

  1. рдирд┐рдпрдВрддреНрд░рдХ рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдПрдБ
  2. рдЗрд╕реЗ routing.ts рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ
  3. рд╡рд┐рдзрд┐рдпреЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░реЗрдВ
  4. рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рдзрд┐ рдореЗрдВ, рдЗрдирдкреБрдЯ / рдЖрдЙрдЯрдкреБрдЯ рд╕рд░реНрдХрд┐рдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ
  5. рдЗрди рдпреЛрдЬрдирд╛рдУрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░реЗрдВ
  6. рдЗрди рдпреЛрдЬрдирд╛рдУрдВ рдХреЛ routing.ts рдореЗрдВ рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВ

рдпрджрд┐ рдЖрдиреЗ рд╡рд╛рд▓рд╛ рдкреИрдХреЗрдЯ рдпреЛрдЬрдирд╛ рд╕реЗ рдореЗрд▓ рдирд╣реАрдВ рдЦрд╛рддрд╛ рд╣реИ, рддреЛ рд╣рдорд╛рд░реА REST рд╕реЗрд╡рд╛ рдХреЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ 400 рддреНрд░реБрдЯрд┐ рдкреНрд░рд╛рдкреНрдд рд╣реЛрдЧреА рдЬреЛ рдХрд┐ рдмрд┐рд▓реНрдХреБрд▓ рдЧрд▓рдд рд╣реИред рдпрджрд┐ рдЖрдЙрдЯрдЧреЛрдЗрдВрдЧ рдкреИрдХреЗрдЯ рдЕрдорд╛рдиреНрдп рд╣реИ, рддреЛ 500 рддреНрд░реБрдЯрд┐ рдЙрддреНрдкрдиреНрди рд╣реЛрдЧреАред

рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдФрд░ рдЕрднреА рднреА рдПрдХ рд╕реБрдЦрдж trifle рдХреЗ рд░реВрдк рдореЗрдВред рд╕реНрд╡реИрдЧрд░ рдпреВрдЖрдИ рдореЗрдВ, рдЖрдк рдХрд┐рд╕реА рднреА рд╡рд┐рдзрд┐ рдкрд░ " рдЗрд╕реЗ рдЖрдЬрд╝рдорд╛рдПрдВ " рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЖрдкрдХреА рдЪрд▓рдиреЗ рд╡рд╛рд▓реА рд╕реЗрд╡рд╛ рдХреЗ рд▓рд┐рдП рдХрд░реНрд▓ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдХ рдЕрдиреБрд░реЛрдз рдЙрддреНрдкрдиреНрди рд╣реЛрдЧрд╛, рдФрд░ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЖрдк рддреБрд░рдВрдд рдкрд░рд┐рдгрд╛рдо рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВред рдФрд░ рдмрд╕ рдЗрд╕рдХреЗ рд▓рд┐рдП рд╕рд░реНрдХрд┐рдЯ рдореЗрдВ рдкреИрд░рд╛рдореАрдЯрд░ " рдЙрджрд╛рд╣рд░рдг " рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдирд╛ рдмрд╣реБрдд рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИред рдХреНрдпреЛрдВрдХрд┐ рдЕрдиреБрд░реЛрдз рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рддреИрдпрд╛рд░ рдкреИрдХреЗрдЬ рдХреЗ рд╕рд╛рде рддреБрд░рдВрдд рдЙрддреНрдкрдиреНрди рд╣реЛрдЧрд╛ред



рдирд┐рд╖реНрдХрд░реНрд╖


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

рдЕрдм рдкреНрд░рд▓реЗрдЦрди рд╣рдореЗрд╢рд╛ рдСрдирд▓рд╛рдЗрди рд╣реЛрддрд╛ рд╣реИ рдФрд░ рд╣рдореЗрд╢рд╛ рдХрдбрд╝рд╛рдИ рд╕реЗ рдХреЛрдб рд╕реЗ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИ - рдФрд░ рдпрд╣ рдореБрдЦреНрдп рдмрд╛рдд рд╣реИред
рдЕрдиреНрдп рдХреНрдпрд╛ рд╡рд┐рдЪрд╛рд░ рд╣реИрдВ?

рдХреНрдпрд╛ рдПрдХреНрд╕рдкреНрд░реЗрд╕ рд╕рдорд░реНрдерди рдЬреЛрдбрд╝рдирд╛ рд╕рдВрднрд╡ рд╣реИ?
рдореИрдВ рдЕрднреА рдЗрд╕реЗ рдкрдврд╝рддрд╛ рд╣реВрдВ ред

рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рдмрд╛рд░ рдПрдХ рд╣реА рд╕реНрдерд╛рди рдкрд░ рд╕рдВрд╕реНрдерд╛рдУрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ред рдХреНрдпреЛрдВрдХрд┐ рдЕрдм рд╕рд░реНрдХрд┐рдЯ рдФрд░ рдЗрдВрдЯрд░рдлреЗрд╕ рджреЛрдиреЛрдВ рдХреЛ рд╕рдВрдкрд╛рджрд┐рдд рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред

рд╢рд╛рдпрдж рдЖрдкрдХреЗ рдкрд╛рд╕ рдХреБрдЫ рджрд┐рд▓рдЪрд╕реНрдк рд╡рд┐рдЪрд╛рд░ рд╣реЛрдВрдЧреЗред рдмреЗрд╣рддрд░ рдЕрднреА рддрдХ рдЦреАрдВрдЪреЛ рдЕрдиреБрд░реЛрдз :)
рдпреЛрдЧрджрд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдкрдХрд╛ рд╕реНрд╡рд╛рдЧрдд рд╣реИред

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


All Articles