рдЬрдВрдЧ рдореЗрдВ рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рддрдХрдиреАрдХ: рд╣рдордиреЗ рдПрдХреНрд╕реЛрдирдо рдХрд╛ рд▓реЛрд╣рд╛ рд╕реЗ рдПрдХреНрдЯрд┐рдХреНрд╕-рд╡реЗрдм рдореЗрдВ рдЕрдиреБрд╡рд╛рдж рдХреИрд╕реЗ рдХрд┐рдпрд╛

рдЬрдВрдЧ рдкрд╛рд░рд┐рд╕реНрдерд┐рддрд┐рдХреА рддрдВрддреНрд░ рдЕрднреА рддрдХ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдирд╣реАрдВ рд╣реБрдЖ рд╣реИред рдирдИ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдЕрдХреНрд╕рд░ рдЗрд╕рдореЗрдВ рджрд┐рдЦрд╛рдИ рджреЗрддреА рд╣реИрдВ, рдЬреЛ рдЕрдкрдиреЗ рдкреВрд░реНрд╡рд╡рд░реНрддрд┐рдпреЛрдВ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдХрд╛рдлреА рдмреЗрд╣рддрд░ рд╣реИрдВ, рдФрд░ рдкрд╣рд▓реЗ рдХреЗ рд▓реЛрдХрдкреНрд░рд┐рдп рдврд╛рдВрдЪреЗ рдЕрдкреНрд░рдЪрд▓рд┐рдд рд╣реЛ рдЧрдП рд╣реИрдВред рдпрд╣ рд╡рд╣реА рд╣реИ рдЬреЛ рдПрдХреНрд╕реЛрдирдо рд╡рд┐рдХрд╕рд┐рдд рдХрд░рддреЗ рд╕рдордп рд╣рдордиреЗ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рдЖрдпрд░рди рд╡реЗрдм рдврд╛рдВрдЪреЗ рдХреЗ рд╕рд╛рде рд╣реБрдЖ рдерд╛ред

рдПрдХреНрдЯрд┐рдХреНрд╕-рд╡реЗрдм рдХреЛ рдЖрдпрд░рди рдХреЗ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди рдХреЗ рд░реВрдк рдореЗрдВ рдЪреБрдирд╛ рдЧрдпрд╛ рдерд╛ред рдЖрдЧреЗ рдореИрдВ рдмрддрд╛рдКрдВрдЧрд╛ рдХрд┐ рдХреИрд╕реЗ рд╣рдордиреЗ рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рддрдХрдиреАрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдореМрдЬреВрджрд╛ рдХреЛрдб рдХреЛ рдПрдХ рдирдП рд╕рдорд╛рдзрд╛рди рдореЗрдВ рдкреЛрд░реНрдЯ рдХрд┐рдпрд╛ред


рдЕрд▓реНрд▓реЗрдУ рдкреАрдбреА рдХреА рдЫрд╡рд┐

рд╣рдордиреЗ рдЖрдпрд░рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд┐рдпрд╛


рдПрдХреНрд╕реЛрдирдо рдореЗрдВ, рд▓реЛрд╣реЗ рдХреЗ рдврд╛рдВрдЪреЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдмрд┐рдирд╛ рдХрд┐рд╕реА рд╕рд╛рд░ рдХреЗ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рд╣рдордиреЗ рдХреБрдЫ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдкрд░ рд╣реИрдВрдбрд▓рд░ рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдП, рд╕рд╣рд╛рдпрдХ рд╡рд┐рдзрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ URL рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рдХреЗ рдХреНрд╡реЗрд░реА рдкреИрд░рд╛рдореАрдЯрд░ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдП, рдФрд░ рдкрд░рд┐рдгрд╛рдо рдХреЛ рдХреЗрд╡рд▓ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рд░реВрдк рдореЗрдВ рд╡рд╛рдкрд╕ рдХрд┐рдпрд╛ред

рдпрд╣ рд╕рдм рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рдерд╛:

fn set_blocks_response(self, router: &mut Router) { let blocks = move |req: &mut Request| -> IronResult<Response> { let count: usize = self.required_param(req, "count")?; let latest: Option<u64> = self.optional_param(req, "latest")?; let skip_empty_blocks: bool = self.optional_param(req, "skip_empty_blocks")? .unwrap_or(false); let info = self.blocks(count, latest.map(Height), skip_empty_blocks)?; self.ok_response(&::serde_json::to_value(info).unwrap()) }; router.get("/v1/blocks", blocks, "blocks"); } 

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

рдЖрдкрдХреЛ рдЙрд╕реЗ рдХреНрдпреЛрдВ рдЫреЛрдбрд╝рдирд╛ рдкрдбрд╝рд╛


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

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

рд╣рдордиреЗ рдПрдХреНрдЯрд┐рдХреНрд╕-рд╡реЗрдм рдкрд░ рд╕реНрд╡рд┐рдЪ рдХреНрдпреЛрдВ рдХрд┐рдпрд╛


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

рдмреЗрд╢рдХ, рдПрдХреНрдЯрд┐рдХреНрд╕-рд╡реЗрдм рдореЗрдВ рдЦрд╛рдорд┐рдпрд╛рдВ рдереАрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЗрд╕рдореЗрдВ рдмрдбрд╝реА рдорд╛рддреНрд░рд╛ рдореЗрдВ рдЕрд╕реБрд░рдХреНрд╖рд┐рдд рдХреЛрдб рдерд╛ред рд▓реЗрдХрд┐рди рдмрд╛рдж рдореЗрдВ рдЗрд╕реЗ рд╕реБрд░рдХреНрд╖рд┐рдд рдЬрдВрдЧ рдореЗрдВ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрд╛ рдЧрдпрд╛, рдЬрд┐рд╕рдиреЗ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░ рджрд┐рдпрд╛ред

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

рд╣рдо рд╡реЗрдм рдлреНрд░реЗрдорд╡рд░реНрдХ рд╕реЗ рдХреНрдпрд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ


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

рдпрд╣ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдпрд╣ рджреГрд╢реНрдп рдХреИрд╕реЗ рджрд┐рдЦрддрд╛ рд╣реИ, рдЖрдЗрдП рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВ рдХрд┐ рдХреЛрдИ HTTP API рдХреНрдпрд╛ рд╣реИ:

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

рдпрджрд┐ рд╣рдо рдЕрдореВрд░реНрддрддрд╛ рдХреА рд╕рднреА рдкрд░рддреЛрдВ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдХрд┐ рдХреЛрдИ HTTP рдЕрдиреБрд░реЛрдз рдХреЗрд╡рд▓ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рд╣реИ:

 fn request(context: &ServiceContext, query: Query) -> Result<Response, ServiceError> 

рдмрд╛рдХреА рд╕рдм рдХреБрдЫ рдЗрд╕ рдореВрд▓ рдЗрдХрд╛рдИ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдорд╛рдирд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╡реЗрдм рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЗ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдКрдкрд░ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рдорд╛рди рд╢реИрд▓реА рдореЗрдВ рд╣реИрдВрдбрд▓рд░ рд▓рд┐рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд HTTP рдЕрдиреБрд░реЛрдз рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП рд╕рдорд╛рдкрди рдмрд┐рдВрджреБ рд╡рд┐рд╢реЗрд╖рддрд╛

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

 // ,   GET .      //    ,      . //         . trait Endpoint: Sync + Send + 'static { type Request: DeserializeOwned + 'static; type Response: Serialize + 'static; fn handle(&self, context: &Context, request: Self::Request) -> Result<Self::Response, io::Error>; } 

рдЙрд╕рдХреЗ рдмрд╛рдж, рдЖрдкрдХреЛ рдЗрд╕ рд╣реИрдВрдбрд▓рд░ рдХреЛ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдврд╛рдВрдЪреЗ рдореЗрдВ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдПрдХреНрдЯрд┐рдХреНрд╕-рд╡реЗрдм рдХреЗ рд▓рд┐рдП рдорд╛рди рд▓реЗрдВ рдХрд┐ рдпрд╣ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд╣реИ:

 //    actix-web.  ,   , //  `Endpoint`   . type FutureResponse = actix_web::FutureResponse<HttpResponse, actix_web::Error>; // ┬л┬╗    actix-web.      //   .     , //     . type RawHandler = dyn Fn(HttpRequest<Context>) -> FutureResponse + 'static + Send + Sync; //   ,     ,     . #[derive(Clone)] struct RequestHandler { ///  . pub name: String, /// HTTP . pub method: actix_web::http::Method, ///  .  ,       . pub inner: Arc<RawHandler>, } 

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

 #[derive(Deserialize)] struct SimpleQuery { a: i32, b: String, } 

рдпрд╣ рд╕рдорд╛рдкрди рдмрд┐рдВрджреБ рд╡рд┐рд╢реЗрд╖рддрд╛ рд╕реЗ рд╕рдВрдмрджреНрдз рдЕрдиреБрд░реЛрдз рдкреНрд░рдХрд╛рд░ рдХреЗ рдЕрдиреБрд░реВрдк рд╣реИред

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

 impl RequestHandler { fn from_endpoint<E: Endpoint>(name: &str, endpoint: E) -> RequestHandler { let index = move |request: HttpRequest<Context>| -> FutureResponse { let context = request.state(); let future = Query::from_request(&request, &()) .map(|query: Query<E::Request>| query.into_inner()) .and_then(|query| endpoint.handle(context, query).map_err(From::from)) .and_then(|value| Ok(HttpResponse::Ok().json(value))) .into_future(); Box::new(future) }; Self { name: name.to_owned(), method: actix_web::http::Method::GET, inner: Arc::from(index) as Arc<RawHandler>, } } } 

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

рд╕рдорд╕реНрдпрд╛рдПрдВ рдЯрд╛рдЗрдк рдХрд░реЗрдВ

рд╣реИрдВрдбрд▓рд░ рд▓рд┐рдЦрддреЗ рд╕рдордп, рдмрд╣реБрдд рд╕рд╛рд░реЗ рд╕рд╣рд╛рдпрдХ рдХреЛрдб рдЙрддреНрдкрдиреНрди рд╣реЛрддреЗ рд╣реИрдВ:

 //    . struct ElementCountEndpoint { elements: Rc<RefCell<Vec<Something>>>, } //   Endpoint. impl Endpoint for ElementCountEndpoint { type Request = (); type Result = usize; fn handle(&self, context: &Context, _request: ()) -> Result<usize, io::Error> { Ok(self.elements.borrow().len()) } } //    . let endpoint = ElementCountEndpoint::new(elements.clone()); let handler = RequestHandler::from_endpoint("/v1/element_count", endpoint); actix_backend.endpoint(handler); 

рдЖрджрд░реНрд╢ рд░реВрдк рд╕реЗ, рдореИрдВ рдПрдХ рд╣реИрдВрдбрд▓рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдмрдВрдж рдХреЛ рдкрд╛рд░рд┐рдд рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛, рдкрд░рд┐рдорд╛рдг рдХреЗ рдПрдХ рдХреНрд░рдо рд╕реЗ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдХреЗ рд╢реЛрд░ рдХреЛ рдХрдо рдХрд░рдирд╛:

 let elements = elements.clone(); actix_backend.endpoint("/v1/elements_count", move || {   Ok(elements.borrow().len()) }); 

рдореИрдВ рдмрд╛рдж рдореЗрдВ рдпрд╣ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реВрдБрдЧрд╛ред

рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдореЗрдВ рдЖрд╕рд╛рди рд╡рд┐рд╕рд░реНрдЬрди


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

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

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

Fn рдкреНрд░рдХрд╛рд░ рд╕реЗ рдкреНрд░рдХрд╛рд░ рдирд┐рдХрд╛рд▓рдирд╛

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

рдореБрдЦреНрдп рд╡рд┐рдЪрд╛рд░ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдлреЙрд░реНрдо рдХреА рдПрдХ рд╕рд╣рд╛рдпрдХ рд╕рдВрд░рдЪрдирд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИ:

 ///       F: Fn(A) -> B. struct SimpleExtractor<A, B, F> {   //   .   inner: F,   _a: PhantomData<A>,   _b: PhantomData<B>, } 

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

рдпрд╣ рд░реБрд╕реНрдд рдкреНрд░рдХрд╛рд░ рдкреНрд░рдгрд╛рд▓реА рдХреА рдпрд╣ рд╕реАрдорд╛ рд╣реИ рдЬреЛ рдПрдХ рд╕рд░рд▓ рд░рдгрдиреАрддрд┐ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИ - рд▓рдЧрднрдЧ рд╕рдорд╛рдкрди рдХреЗ рд▓рд┐рдП рд╕рдорд╛рдкрди рдмрд┐рдВрджреБ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП:

 impl<A, B, F> Endpoint for F where F: Fn(&Context, A) -> B { type Request = A; type Response = B; fn handle(&self, context: &Context, request: A) -> Result<B, io::Error> { // ... } } 

рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рд╕рдВрдХрд▓рдХ рдПрдХ рддреНрд░реБрдЯрд┐ рджреЗрддрд╛ рд╣реИ:

 error[E0207]: the type parameter `A` is not constrained by the impl trait, self type, or predicates --> src/main.rs:10:6 | 10 | impl<A, B, F> Endpoint for F where F: Fn(&Context, A) -> B { | ^ unconstrained type parameter 

SimpleExtractor рдХреА рд╕рд╣рд╛рдпрдХ рд╕рдВрд░рдЪрдирд╛ рдкрд░рд┐рд╡рд░реНрддрди рд╕реЗ рд╡рд░реНрдгрди рдХрд░рдирд╛ рд╕рдВрднрд╡ рдмрдирд╛рддреА рд╣реИред рдпрд╣ рдЖрдкрдХреЛ рдХрд┐рд╕реА рднреА рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╕рд╣реЗрдЬрдиреЗ рдФрд░ рдЗрд╕рдХреЗ рддрд░реНрдХреЛрдВ рдХреЛ рдирд┐рдХрд╛рд▓рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ:

 impl<A, B, F> From<F> for SimpleExtractor<A, B, F> where F: Fn(&Context, A) -> B, A: DeserializeOwned, B: Serialize, { fn from(inner: F) -> Self { SimpleExtractor { inner, _a: PhantomData, _b: PhantomData, } } } 

рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рд╕рдВрдХрд▓рд┐рдд рдХрд░рддрд╛ рд╣реИ:

 #[derive(Deserialize)] struct Query { a: i32, b: String, }; //   . fn my_handler(_: &Context, q: Query) -> String { format!("{} has {} apples.", qb, qa) } let fn_extractor = SimpleExtractor::from(my_handler); //  . let c = 15; let my_closure = |_: &Context, q: Query| -> String { format!("{} has {} apples, but Alice has {}", qb, qa, c) }; let closure_extractor = SimpleExtractor::from(my_closure); 

рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рдФрд░ рдорд╛рд░реНрдХрд░ рдкреНрд░рдХрд╛рд░

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

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

 ///   HTTP-. pub struct With<Q, I, R, F> { ///  -. pub handler: F, ///     . _query_type: PhantomData<Q>, ///   . _item_type: PhantomData<I>, ///  ,  . ///  ,       . _result_type: PhantomData<R>, } //   ,   . impl<Q, I, F> From<F> for With<Q, I, Result<I>, F> where F: Fn(&ServiceApiState, Q) -> Result<I>, { fn from(handler: F) -> Self { Self { handler, _query_type: PhantomData, _item_type: PhantomData, _result_type: PhantomData, } } } //     . impl<Q, I, F> From<F> for With<Q, I, FutureResult<I>, F> where F: Fn(&ServiceApiState, Q) -> FutureResult<I>, { fn from(handler: F) -> Self { Self { handler, _query_type: PhantomData, _item_type: PhantomData, _result_type: PhantomData, } } } 

рдЕрдм рд╣рдореЗрдВ рдПрдХ рдРрд╕реА рд╕рдВрд░рдЪрдирд╛ рдШреЛрд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдЕрдиреБрд░реЛрдзрдХрд░реНрддрд╛ рдХреЛ рдЙрд╕рдХреЗ рдирд╛рдо рдФрд░ рд╡рд┐рд╡рд┐рдзрддрд╛ рдХреЗ рд╕рд╛рде рдЬреЛрдбрд╝рд╛ рдЬрд╛ рд╕рдХреЗ:

 #[derive(Debug)] pub struct NamedWith<Q, I, R, F, K> {   ///  .   pub name: String,   ///    .   pub inner: With<Q, I, R, F>,   ///  .   _kind: PhantomData<K>, } 

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

 /// ,    .  HTTP   GET-. pub struct Immutable; /// ,   .  HTTP   POST, PUT, UPDATE ///    ,        POST. pub struct Mutable; 

рдЕрдм рд╣рдо R рдФрд░ K рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд╕рднреА рд╕рдВрдпреЛрдЬрдиреЛрдВ рдХреЗ рд▓рд┐рдП рдкреНрд░рдХрд╛рд░ рдХреЗ рдЪрд╛рд░ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрдиреЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рд╣реИрдВрдбрд▓рд░ рдХрд╛ рдЕрдиреБрд░реЛрдз рдорд╛рди рдФрд░ рдЕрдиреБрд░реЛрдз рдХрд╛ рдкреНрд░рдХрд╛рд░)ред

 //     get . impl<Q, I, F> From<NamedWith<Q, I, Result<I>, F, Immutable>> for RequestHandler where F: Fn(&ServiceApiState, Q) -> Result<I> + 'static + Send + Sync + Clone, Q: DeserializeOwned + 'static, I: Serialize + 'static, { fn from(f: NamedWith<Q, I, Result<I>, F, Immutable>) -> Self { let handler = f.inner.handler; let index = move |request: HttpRequest| -> FutureResponse { let context = request.state(); let future = Query::from_request(&request, &()) .map(|query: Query<Q>| query.into_inner()) .and_then(|query| handler(context, query).map_err(From::from)) .and_then(|value| Ok(HttpResponse::Ok().json(value))) .into_future(); Box::new(future) }; Self { name: f.name, method: actix_web::http::Method::GET, inner: Arc::from(index) as Arc<RawHandler>, } } } //     post . impl<Q, I, F> From<NamedWith<Q, I, Result<I>, F, Mutable>> for RequestHandler where F: Fn(&ServiceApiState, Q) -> Result<I> + 'static + Send + Sync + Clone, Q: DeserializeOwned + 'static, I: Serialize + 'static, { fn from(f: NamedWith<Q, I, Result<I>, F, Mutable>) -> Self { let handler = f.inner.handler; let index = move |request: HttpRequest| -> FutureResponse { let handler = handler.clone(); let context = request.state().clone(); request .json() .from_err() .and_then(move |query: Q| { handler(&context, query) .map(|value| HttpResponse::Ok().json(value)) .map_err(From::from) }) .responder() }; Self { name: f.name, method: actix_web::http::Method::POST, inner: Arc::from(index) as Arc<RawHandler>, } } } //     get . impl<Q, I, F> From<NamedWith<Q, I, FutureResult<I>, F, Immutable>> for RequestHandler where F: Fn(&ServiceApiState, Q) -> FutureResult<I> + 'static + Clone + Send + Sync, Q: DeserializeOwned + 'static, I: Serialize + 'static, { fn from(f: NamedWith<Q, I, FutureResult<I>, F, Immutable>) -> Self { let handler = f.inner.handler; let index = move |request: HttpRequest| -> FutureResponse { let context = request.state().clone(); let handler = handler.clone(); Query::from_request(&request, &()) .map(move |query: Query<Q>| query.into_inner()) .into_future() .and_then(move |query| handler(&context, query).map_err(From::from)) .map(|value| HttpResponse::Ok().json(value)) .responder() }; Self { name: f.name, method: actix_web::http::Method::GET, inner: Arc::from(index) as Arc<RawHandler>, } } } //     post . impl<Q, I, F> From<NamedWith<Q, I, FutureResult<I>, F, Mutable>> for RequestHandler where F: Fn(&ServiceApiState, Q) -> FutureResult<I> + 'static + Clone + Send + Sync, Q: DeserializeOwned + 'static, I: Serialize + 'static, { fn from(f: NamedWith<Q, I, FutureResult<I>, F, Mutable>) -> Self { let handler = f.inner.handler; let index = move |request: HttpRequest| -> FutureResponse { let handler = handler.clone(); let context = request.state().clone(); request .json() .from_err() .and_then(move |query: Q| { handler(&context, query) .map(|value| HttpResponse::Ok().json(value)) .map_err(From::from) }) .responder() }; Self { name: f.name, method: actix_web::http::Method::POST, inner: Arc::from(index) as Arc<RawHandler>, } } } 

рдмреИрдХрдПрдВрдб рдХреЗ рд▓рд┐рдП "рдореБрдЦреМрдЯрд╛"

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

 pub struct ServiceApiScope { actix_backend: actix::ApiBuilder, } impl ServiceApiScope { ///    Immutable    . pub fn endpoint<Q, I, R, F, E>(&mut self, name: &'static str, endpoint: E) -> &mut Self where //     ,      : Q: DeserializeOwned + 'static, I: Serialize + 'static, F: Fn(&ServiceApiState, Q) -> R + 'static + Clone, E: Into<With<Q, I, R, F>>, //  ,          //  NamedWith  RequestHandler. RequestHandler: From<NamedWith<Q, I, R, F, Immutable>>, { self.actix_backend.endpoint(name, endpoint); self } ///    Mutable . pub fn endpoint_mut<Q, I, R, F, E>(&mut self, name: &'static str, endpoint: E) -> &mut Self where Q: DeserializeOwned + 'static, I: Serialize + 'static, F: Fn(&ServiceApiState, Q) -> R + 'static + Clone, E: Into<With<Q, I, R, F>>, RequestHandler: From<NamedWith<Q, I, R, F, Mutable>>, { self.actix_backend.endpoint_mut(name, endpoint); self } 

рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдЕрдиреБрд░реЛрдз рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рдкреНрд░рдХрд╛рд░, рдЗрд╕рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХреЗ рдкреНрд░рдХрд╛рд░, рд╕рд╛рде рд╣реА рд╣реИрдВрдбрд▓рд░ рдХреА рд╕рдордХрд╛рд▓рд┐рдХрддрд╛ / рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХрддрд╛ рдЕрдкрдиреЗ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рд╕реЗ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдкреНрд░рд╛рдкреНрдд рд╣реЛрддреА рд╣реИред рдЗрд╕рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд, рдЖрдкрдХреЛ рдЕрдиреБрд░реЛрдз рдХреЗ рдирд╛рдо рдХреЗ рд╕рд╛рде-рд╕рд╛рде рдЗрд╕рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рднреА рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред

рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдиреБрдХрд╕рд╛рди


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

рдПрдХ рдФрд░ рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдЖрдк рдЕрддрд┐рд░рд┐рдХреНрдд рддрд░реНрдХ рдХреЗ рдмрд┐рдирд╛ рдХрд┐рд╕реА рд╣реИрдВрдбрд▓рд░ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗред рджреВрд╕рд░реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ, рдпрджрд┐ рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рд╕рдВрдХрд▓рди рдирд╣реАрдВ рдХрд░реЗрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдореМрдЬреВрджрд╛ рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд╕рд╛рде рд╕рдВрдШрд░реНрд╖ рдХрд░рддрд╛ рд╣реИ:

 impl<(), I, F> From<F> for With<(), I, Result<I>, F> where F: Fn(&ServiceApiState) -> Result<I>, { fn from(handler: F) -> Self { Self { handler, _query_type: PhantomData, _item_type: PhantomData, _result_type: PhantomData, } } } 

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

рдЗрд╕реА рддрд░рд╣, рдЖрдк рд░рд┐рдЯрд░реНрди рд╡реИрд▓реНрдпреВ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддреЗред рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЕрдЧрд░ рдЕрдиреБрд░реЛрдз рдЗрд╕реЗ рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рддреЛ рдпрд╣ рд╣рдореЗрд╢рд╛ JSON рдХреЛ рд╢реВрдиреНрдп рдХреЗ рд╕рд╛рде рд▓реМрдЯрд╛рдПрдЧрд╛ред

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

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


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

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


All Articles