рдЦреЗрд▓рдиреЗ рдХреЗ рд▓рд┐рдП! рд▓рд┐рдлреНрдЯ! Srsly?

рдЦреЗрд▓рдиреЗ рдХреЗ рд▓рд┐рдП! рдФрд░ рд▓рд┐рдлреНрдЯ, рдпреЗ рджреЛ рд░реВрдкрд░реЗрдЦрд╛рдПрдВ рд╣реИрдВ, рдЬрд╣рд╛рдВ рд╕реНрдХрд╛рд▓рд╛ рд╡реЗрдм рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХрд╛ рдореБрдЦреНрдп рдкреНрд░рд╡рд╛рд╣ рд╣реЛ рд░рд╣рд╛ рд╣реИред рд╕рдЪ рдореЗрдВ, рд╕реНрдХрд╛рд▓рд╛ рдХреЗ рд▓рд┐рдП рд╕реНрдЯреИрдХ рдУрд╡рд░рдлреНрд▓реЛ рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЛ рджреЗрдЦрдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ рдФрд░ рдЖрдк рд╕рдордЭ рдЬрд╛рдПрдВрдЧреЗ рдХрд┐ рдореИрдВ рд╕рд╣реА рд╣реВрдВред рдореЗрд░рд╛ рдорд╛рдирдирд╛ тАЛтАЛрд╣реИ рдХрд┐ рдЬрдЯрд┐рд▓ рд╣рд╛рд░реНрд╡реЗрд╕реНрдЯрд░ рд╕реЗ рддрдВрдЧ рдЖ рдЪреБрдХреЗ рд▓реЛрдЧреЛрдВ рдХрд╛ рдкреНрд░рддрд┐рд╢рдд рдЕрдзрд┐рдХ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореИрдВ "рдЕрдиреНрдп" Xitrum рдврд╛рдВрдЪреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реВрдВрдЧрд╛ ред

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

рддреБрд░рдВрдд рдкреНрд░рджрд░реНрд╢рди рдкрд░ред рдиреНрдпреВрдирддрдо рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдореЗрдВ, xitrum 64Mb рдХреА рдореЗрдореЛрд░реА рд╕реАрдорд╛ рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдФрд░ рдЪрд▓рддрд╛ рд╣реИред CPU рд╕рдордп рд▓рд╛рдЧрдд рдорд╣рддреНрд╡рдкреВрд░реНрдг рдирд╣реАрдВ рд╣реИрдВ, рдЕрд░реНрдерд╛рддреН рдлреНрд░реЗрдорд╡рд░реНрдХ рд╕реНрд╡рдпрдВ рдкреНрд░реЛрд╕реЗрд╕рд░ рдХреЛ рд▓реЛрдб рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИред рдмрд╛рдХреА рд╕рдм рдЖрдкрдХреЗ рдКрдкрд░ рд╣реИред

рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕рдореАрдХреНрд╖рд╛рдПрдБ
рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рд╡реЗрдмрд╕рд╛рдЗрдЯ рд╕реЗ:
рд╡рд╛рд╣, рдпрд╣ рдХрд╛рдо рдХрд╛ рдПрдХ рдмрд╣реБрдд рдкреНрд░рднрд╛рд╡рд╢рд╛рд▓реА рд╢рд░реАрд░ рд╣реИ, рдпрдХреАрдирди рд▓рд┐рдлреНрдЯ рдХреЗ рдмрд╛рд╣рд░ рд╕рдмрд╕реЗ рдкреВрд░реНрдг рд╕реНрдХрд╛рд▓рд╛ рдлреНрд░реЗрдорд╡рд░реНрдХ (рд▓реЗрдХрд┐рди рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЖрд╕рд╛рди)ред

Xitrum рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рдкреВрд░реНрдг рд╕реНрдЯреИрдХ рд╡реЗрдм рдлреНрд░реЗрдорд╡рд░реНрдХ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рд╕рднреА рдард┐рдХрд╛рдиреЛрдВ рдХреЛ рд╢рд╛рдорд┐рд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ wtf-am-I-on-the-moon рдПрдХреНрд╕реНрдЯреНрд░рд╛ рдХрд▓рд╛рдХрд╛рд░ рдЬреИрд╕реЗ ETags, рд╕реНрдерд┐рд░ рдлрд╝рд╛рдЗрд▓ рдХреИрд╢ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдФрд░ рдСрдЯреЛ-рдЧрдЬрд╝рд┐рдк рд╕рдВрдкреАрдбрд╝рди рд╢рд╛рдорд┐рд▓ рд╣реИрдВред рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд JSON рдХрдирд╡рд░реНрдЯрд░ рдкрд░, рдЗрдВрдЯрд░рд╕реЗрдкреНрдЯрд░ рд╕реЗ рдкрд╣рд▓реЗ / рдЖрд╕рдкрд╛рд╕ / рдмрд╛рдж рдореЗрдВ, рдЕрдиреБрд░реЛрдз / рд╕рддреНрд░ / рдХреБрдХреА / рдлреНрд▓реИрд╢ рд╕реНрдХреЛрдк, рдПрдХреАрдХреГрдд рд╕рддреНрдпрд╛рдкрди (рд╕рд░реНрд╡рд░ рдФрд░ рдХреНрд▓рд╛рдЗрдВрдЯ-рд╕рд╛рдЗрдб, рдЕрдЪреНрдЫрд╛), рдмрд┐рд▓реНрдЯ-рдЗрди рдХреИрд╢ рд▓реЗрдпрд░ (рд╣реЗрдЬрд╝реЗрд▓рдХрд╛рд╕реНрдЯ), i18n a la GNU рдЧреЗрдЯрдЯреЗрдХреНрд╕реНрдЯ , рдиреЗрдЯреНрдЯреА (рдирдЧреНрдиреЗрдХреНрд╕ рдХреЗ рд╕рд╛рде, рд╣реИрд▓реЛ рддреЗрдЬ рдзрдзрдХрддреЗ рд╣реБрдП), рдЖрджрд┐ред рдФрд░ рддреБрдореНрд╣рд╛рд░реЗ рдкрд╛рд╕ рд╣реИ, рд╡рд╛рд╣ред

рдореЗрд░реА рд░рд╛рдп:
рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рдврд╛рдВрдЪрд╛ рдореИрдВрдиреЗ рдХрднреА рд╕реНрдХрд╛рд▓рд╛ / рдЬрд╛рд╡рд╛ рдХреЗ рд▓рд┐рдП рджреЗрдЦрд╛ рд╣реИред Xitrum рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдореБрдЭреЗ рдкрдХрдбрд╝рддрд╛ рд╣реИ, рдпрд╣ рд╕реНрдерд┐рд░ рдЯрд╛рдЗрдкрд┐рдВрдЧ рдХреЗ рд╕рд╛рде рдбрд╛рдВрд╕рд░ + рд░реЗрд▓реНрд╕ рдХреЗ рдорд┐рд╢реНрд░рдг рдХреА рддрд░рд╣ рд╣реИ, рдЕрджреНрднреБрдд!



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

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


рд╕рдордп рдХреЗ рд╕рд╛рде, рдХрдИ рд▓реЛрдЧреЛрдВ рдиреЗ рдврд╛рдВрдЪреЗ рдХреЗ рд╡рд┐рдХрд╛рд╕ рдореЗрдВ рднрд╛рдЧ рд▓рд┐рдпрд╛ред рдлрд┐рд▓рд╣рд╛рд▓, Xitrum рдХреЛрд░ рдХреЛ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓реА рдЯреАрдо рдореЗрдВ рджреЛ рд▓реЛрдЧ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ: рдУрд╢рд┐рджрд╛ рдФрд░ рдПрдирдЧреЙрдХ ред


рддреЛ xitrum:


Xitrum рдирд┐рдпрдВрддреНрд░рдХ-рдкрд╣рд▓рд╛ рдврд╛рдВрдЪрд╛ рд╣реИред рд░рдирдЯрд╛рдЗрдо рдХреЗ рджреМрд░рд╛рди рдирд┐рдпрдВрддреНрд░рдХ рд╡рд┐рдЪрд╛рд░реЛрдВ рдХреЛ рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рдмрджрд▓рдирд╛ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реИ, рдЬреЛ рдХреБрдЫ рд╕реНрдХрд╛рд▓рд╛ / рдЬрд╛рд╡рд╛ рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЗ рд▓рд┐рдП рддреБрдЪреНрдЫ рдирд╣реАрдВ рд╣реИред рдореЗрд░реА рд╕реНрдореГрддрд┐ рдореЗрдВ, рдпрд╣ рдЖрдорддреМрд░ рдкрд░ рдЬрд╛рд╡рд╛ рджреБрдирд┐рдпрд╛ рд╕реЗ рдПрдХрдорд╛рддреНрд░ рдлреНрд░реЗрдорд╡рд░реНрдХ рд╣реИ рдЬреЛ рд╕реАрдПрдордПрд╕ рдХреЛ рдмрд┐рдирд╛ рдХрд┐рд╕реА рдмреИрд╕рд╛рдЦреА рдХреЗ рдЧрддрд┐рд╢реАрд▓ рдЯреЗрдВрдкрд▓реЗрдЯрд┐рдВрдЧ рдХреЗ рд╕рд╛рде рд▓рд┐рдЦрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдкрд╛рдардХ рдХреЛ рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреА рдореВрд▓ рдмрд╛рддреЛрдВ рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рдХрд░рд╛рдирд╛ рдЙрдЪрд┐рдд рд╣реЛрдЧрд╛, рдореИрдВ рдПрдХ рдФрд░ рдмрд╛рд░ рдЬрдЯрд┐рд▓ рдЪреАрдЬреЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░реВрдВрдЧрд╛ рдЕрдЧрд░ рдЗрд╕рдореЗрдВ рд░реБрдЪрд┐ рд╣реЛред

рдПрдХ рд░рд┐рдХреНрдд рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдФрд░ рдлрд╝реЛрд▓реНрдбрд░ рд╕рдВрд░рдЪрдирд╛ рдмрдирд╛рдПрдБ
рдПрдХ рдирдИ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдмрдирд╛рдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рдЖрд╕рд╛рди рддрд░реАрдХрд╛ рд╣реИ:
git clone https://github.com/ngocdaothanh/xitrum-new my-app cd my-app sbt/sbt run 

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

рдХрд┐рд╕реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЛ рдЧреНрд░рд╣рдг рдореЗрдВ рдЖрдпрд╛рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдо sbt / sbt рдЧреНрд░рд╣рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рд╡рд┐рдЪрд╛рд░ sbt / sbt рдЬрди-рд╡рд┐рдЪрд╛рд░ рдореЗрдВ ред
рдорд╣рддреНрд╡рдкреВрд░реНрдг: рдЧреНрд░рд╣рдг рдореЗрдВ рдЖрдкрдХреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдХреНрд▓рд╛рд╕рдкрде рдкрд░ рдХреЙрдиреНрдлрд┐рдЧ рдлрд╝реЛрд▓реНрдбрд░ рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛, рдЕрдиреНрдпрдерд╛ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдЧреНрд░рд╣рдг ( sbt-eclipse # 182 рдмрдЧ) рд╕реЗ рд╢реБрд░реВ рдирд╣реАрдВ рд╣реЛрдЧреАред

рдкрд░рд┐рдпреЛрдЬрдирд╛ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рд╕рдВрд░рдЪрдирд╛:
 ./script #      production ./config #   (akka, logback, xitrum) ./public #    (css, js, ) ./project # sbt ./src # src ./src/main/scalate #    ./src/main/scala # scala  ./src/main/scala/quickstart/Boot.scala #     



рд╕рд░рд▓ рдирд┐рдпрдВрддреНрд░рдХ


рдПрдХреНрд╕рдЯреНрд░рдо рдореЗрдВ, рдкреНрд░рддреНрдпреЗрдХ рдЕрдиреБрд░реЛрдз рдХреЛ рдХреЗрд╡рд▓ рдПрдХреНрд╢рди рд╕реЗ рдЗрдирд╣реЗрд░рд┐рдЯрд░ рджреНрд╡рд╛рд░рд╛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЕрд░реНрдерд╛рддреН, рд╣рдорд╛рд░реЗ рд╕рд░реНрд╡рд░ рджреНрд╡рд╛рд░рд╛ рд╕рдВрд╕рд╛рдзрд┐рдд рдкреНрд░рддреНрдпреЗрдХ рд╕реНрд╡рддрдВрддреНрд░ рдорд╛рд░реНрдЧ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдПрдХ рдЕрд▓рдЧ рдирд┐рдпрдВрддреНрд░рдХ рд╡рд░реНрдЧ рдШреЛрд╖рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

 import xitrum.Action import xitrum.annotation.GET @GET("url/to/HelloAction") class HelloAction extends Action { def execute() { respondHtml( <xml:group> <p>Hello world!</p> </xml:group> ) } } 

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

 @GET("url/to/HelloAction") class HelloAction extends Action { def execute() { Thread.sleep(1000) // :    Netty  respond() } } 

рдирд┐рдпрдВрддреНрд░рдХ рдХреЗ рдЗрд╕ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд╕рд╛рде, рдЖрдкрдХрд╛ рд╕рд░реНрд╡рд░ рдкреНрд░рддрд┐ рд╕реЗрдХрдВрдб 1 рд╕реЗ рдЕрдзрд┐рдХ рдХрдиреЗрдХреНрд╢рди рдХреА рд╕реЗрд╡рд╛ рджреЗрдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдирд╣реАрдВ рд╣реИред рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ FutureAction рдпрд╛ ActorAction рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред


рдорд╛рд░реНрдЧ



Xitrum GET, POST, рдФрд░ рдЕрдзрд┐рдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ HTTP рдЕрдиреБрд░реЛрдзреЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИред рдХреЛрдИ рднреА рдирд┐рдпрдВрддреНрд░рдХ рдЕрд╕реАрдорд┐рдд рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдорд╛рд░реНрдЧреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓ рд╕рдХрддрд╛ рд╣реИред рдЖрдк рдкрд╣рд▓реЗ рдФрд░ рдЕрдВрддрд┐рдо рдПрдиреЛрдЯреЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдирд┐рдпрдВрддреНрд░рдХреЛрдВ рдХреЗ рдХреНрд░рдо рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдирд┐рдпрдВрддреНрд░рдХ рдХреЛ METHOD (": *") рдХреЗ рд░реВрдк рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ

 @GET("url1") @First class A extends Action { ... } @GET("url1", "url2", "...") @POST("url1", ...) class B extends Action { ... } @GET(":*") @Last class Default extends Action { ... } 

рдирд┐рдпрдВрддреНрд░рдХ рдХрд╛ рд╕рдВрджрд░реНрдн рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХреНрд╢рди рдПрдХ рдпреВрдЖрд░рдПрд▓ рд╡рд┐рдзрд┐ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдЬреАрдИрдЯреА рд▓рд┐рдВрдХ рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИред

 url[HelloAction]("name" -> "caiiiycuk") // url/to/HelloAction?name=caiiiycuk 

рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдпрд╛ classpath рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рд╕реЗ рд╕реНрдерд┐рд░ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХрд╛ рд▓рд┐рдВрдХ рдХреНрд░рдорд╢рдГ publicUrl рдФрд░ resourceUrl рд╡рд┐рдзрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдХреНрд▓рд╛рд╕рд┐рдХ рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ рдлреЙрд░рд╡рд░реНрдбрдЯреЛ рдФрд░ рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯреЛ рдЬреИрд╕реЗ рд╕рдорд░реНрдерд┐рдд рд╣реИрдВ ред

рдкреИрд░рд╛рдореАрдЯрд░ рд╡рд┐рд╢реНрд▓реЗрд╖рдг



Xitrum рдЖрдкрдХреЛ рддреАрди рдкреНрд░рдХрд╛рд░ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рдкрд╛рд░рджрд░реНрд╢реА рд░реВрдк рд╕реЗ рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ:


рдорд╛рдкрджрдВрдбреЛрдВ рддрдХ рдкрд╣реБрдВрдЪ рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИ:

 param("X") //   X  String,      params("X") //   X  List[String],      paramo("X") //   X  Option[String] paramso("X") //   X  Option[List[String]] param[Type]("X") //   X  [Type],      params[Type]("X") //   X  List[[Type]],      paramo[Type]("X") //   X  Option[[Type]] paramso[Type]("X") //   X  Option[List[[Type]]] 

pathParams рдХреЛ рдкреНрд░рддреАрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд░реЗрд▓ рдХреЗ рд╕рд╛рде рд╕рдорд╛рдирддрд╛ рд╕реЗ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ: '(: id ,: рд▓реЗрдЦ ,: рдЖрджрд┐), рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдкреИрд░рд╛рдореАрдЯрд░ рдорд╛рди' <> '(рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП: рдЖрдИрдбреА <0-9) + рдореЗрдВ рд╕рдВрд▓рдЧреНрди рдирд┐рдпрдорд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕реАрдорд┐рдд рдХрд┐рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред >)ред

 @GET("articles/:id<[0-9]+>", "articles/:id<[0-9]+>.:format") class ArticlesShow extends Action { def execute() { val id = param[Int]("id") val format = paramo("format").getOrElse("json") ... } } 

рдХрднреА-рдХрднреА POST рдЕрдиреБрд░реЛрдз рдХреЗ рдореБрдЦреНрдп рднрд╛рдЧ рдХреЗ рдмрд╛рдЗрдирд░реА рдбреЗрдЯрд╛ рдХреЛ рдкрдврд╝рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рдпрд╣ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:

 val body = requestContentString //  String val bodyMap = requestContentJson[Type] //  Json,  Type val raw = request.getContent //  ByteBuf 


рдорд╛рдирдХреАрдХрд░рдг



Xitrum рдореЗрдВ рдПрдХ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрди рдирд╣реАрдВ рд╣реИ, рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрди рдХреЗ рдмрд┐рдирд╛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдкреНрд░рдХрд╛рд░ рдЙрддреНрдкрдиреНрди рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ:


рдЪреМрдВрдХрд╛ рджрд┐рдпрд╛ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╕рдорд░реНрдерди
рдпрд╣ рд╕реНрдерд┐рддрд┐ рддрдм рд╣реЛрддреА рд╣реИ рдЬрдм рдЕрдиреБрд░реЛрдз рдХреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╕рд░реНрд╡рд░ рдХреА рдореЗрдореЛрд░реА рдореЗрдВ рдирд╣реАрдВ рд░рдЦреА рдЬрд╛рддреА рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░рд╛ рд╕рд░реНрд╡рд░ CSV рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рдПрдХ рд╡рд╛рд░реНрд╖рд┐рдХ рд░рд┐рдкреЛрд░реНрдЯ рддреИрдпрд╛рд░ рдХрд░рддрд╛ рд╣реИред рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд░реВрдк рд╕реЗ, рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рд╣рдо рдкреВрд░реА рд░рд┐рдкреЛрд░реНрдЯ рдХреЛ рдореЗрдореЛрд░реА рдореЗрдВ рд╕реЗрд╡ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдПрдХ рдЙрддреНрддрд░ рдХреЗ рд╕рд╛рде рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рднреЗрдЬ рд╕рдХрддреЗ рд╣реИрдВред рдШреБрдЯрди рднрд░рд╛ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдЬреАрд╡рди рдЪрдХреНрд░:
  1. рдХреЙрд▓ рд╕реЗрдЯ рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░реЗрдВ
  2. рдХреЙрд▓ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ * () рдЬрд┐рддрдиреА рдмрд╛рд░ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ
  3. рдЬрдм рд╕рднреА рдбреЗрдЯрд╛ рднреЗрдЬрд╛ рдЧрдпрд╛ рд╣реЛ, рддрдм answerLastChunk рдХреЛ рдХреЙрд▓ рдХрд░реЗрдВ

 val generator = new MyCsvGenerator setChunked() respondText(header, "text/csv") while (generator.hasNextLine) { val line = generator.nextLine respondText(line) } respondLastChunk() 


рдЬрдм ActorAction рдХреЗ рд╕рд╛рде рд╕рдВрдпреЛрдЬрди рдореЗрдВ chunked рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ Facebook BigPipe рдХреЛ рдмрд╣реБрдд рд╕рд░рд▓рддрд╛ рд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред


рдорд╛рдирдХреАрдХрд░рдг рдХреЗ рд▓рд┐рдП , рдЖрдк рд╕реНрдХреЗрд▓реЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╣ рдПрдХ рдЯреЗрдореНрдкрд▓реЗрдЯ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рд╣реИред рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрди рдХрдИ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ: рдореВрдВрдЫреЗрдВ, рд╕реНрдХреИрдЯрд▓, рдЬреЗрдб рдФрд░ рдПрд╕рдкреАрдПрд╕ред рдореИрдВ ssp рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдкрд╕рдВрдж рдХрд░рддрд╛ рд╣реВрдВ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ html рдХреЗ рд╕рдмрд╕реЗ рдХрд░реАрдм рд╣реИред рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ, рдЬреЗрдб рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рддрд╛рдХрд┐ рдЖрдкрдХреЛ xitrum.conf рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдореЗрдВ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдкреНрд░рдХрд╛рд░ рдХреЛ рдмрджрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛ, рд▓рд╛рдЗрди рдХреЛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдЯрд╛рдЗрдк рдХрд░реЗрдВ = рдЬреЗрдб рдХреЛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдЯрд╛рдЗрдк = рдПрд╕рдкреАрдПрд╕ рдХреЗ рд╕рд╛рде рдмрджрд▓реЗрдВред

рд╕реНрдХреИрд▓реЗрдЯ рд╕реБрд╡рд┐рдзрд╛рдПрдБ
  • HTML рд╕рдВрдЧрдд рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ (ssp)
  • HAML рд╕рдорд╛рди рд╕рд┐рдВрдЯреИрдХреНрд╕ (рдЬреЗрдб)
  • рдЙрдбрд╝рд╛рди рдкрд░ рдЯреЗрдореНрдкрд▓реЗрдЯ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рдирд╛ (рд░рди рдЯрд╛рдЗрдо рдкрд░)
  • рд╕рдВрдХрд▓рд┐рдд рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕ (рд╕рдВрдХрд▓рди рдЪрд░рдг рдореЗрдВ рддреНрд░реБрдЯрд┐ рдХреА рдЬрд╛рдБрдЪ)
  • рдПрдХ рдЯреЗрдореНрдкрд▓реЗрдЯ рдореЗрдВ рдПрдХ рдЯреЗрдореНрдкрд▓реЗрдЯ рд╢рд╛рдорд┐рд▓ рд╣реИ
  • рдкреИрдЯрд░реНрди рдХреА рд╡рд┐рд░рд╛рд╕рдд (рдмреНрд▓реЙрдХ рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛)
  • рдЯреИрдЧ рдХреА рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд╕реНрдХреНрд░реАрдирд┐рдВрдЧ
  • рд╕реАрдзреЗ рдПрдХ рдЯреЗрдореНрдкрд▓реЗрдЯ рдореЗрдВ рд╕реНрдХрд╛рд▓рд╛ рдХреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛



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

 src/main/scala/quickstart/action/SiteIndex.scala #   src/main/scalate/quickstart/action/SiteIndex.ssp #   src/main/scalate/quickstart/action/SiteIndex/ #    package quickstart.action import xitrum.annotation.GET @GET("") class SiteIndex extends DefaultLayout { def execute() { respondView() } } 

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, SiteIndex.ssp тАЛтАЛрдЯреЗрдореНрдкреНрд▓реЗрдЯ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдмрд╕ responseView () рдХреЙрд▓ рдХрд░реЗрдВред рдПрдХ рдЯреБрдХрдбрд╝реЗ рдХреА рдЕрд╡рдзрд╛рд░рдгрд╛ рдкреНрд░рджрд╛рди рдХреА рдЬрд╛рддреА рд╣реИ, рдЗрд╕рдХреА рдорджрдж рд╕реЗ рдЖрдк рдирд┐рдпрдВрддреНрд░рдХ рдХреЗ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХреЛ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВред

 @GET("") class SiteIndex extends DefaultLayout { def execute() { respondHtml(renderFragment("some")) #      } } 


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

рдирд┐рдпрдВрддреНрд░рдХрдЯреЗрдореНрдкрд▓реЗрдЯ
 def execute() { at("login") = "caiiiycuk" at("rating") = 5 respondView() } 

 Hello ${at("login")} You rating is ${at("rating")} 


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

рдирд┐рдпрдВрддреНрд░рдХрдЯреЗрдореНрдкрд▓реЗрдЯ
 def random = Random.nextInt def execute() { respondView() } 

 <% val myAction = currentAction.asInstanceOf[MyAction]; import myAction._ %> You random number is ${random} 


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

рдирд┐рдпрдВрддреНрд░рдХрдЯреЗрдореНрдкрд▓реЗрдЯ
 case class User(login: String, name: String) ... def execute() { at("user") = User("admin", "Admin") respondView() } 

 <script type="text/javascript"> var user = ${atJson("user")}; alert(user.login); alert(user.name); </script> 



рд╕рддреНрд░ рдФрд░ рдХреБрдХреАрдЬрд╝



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

 //  requestCookies.get("myCookie") match { case None => ... case Some(string) => ... } //  responseCookies.append(new DefaultCookie("name", "value")) 

Xitrum рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдХреБрдХреАрдЬрд╝ рдореЗрдВ рд╕рддреНрд░ рдХреЛ рдмрдЪрд╛рддрд╛ рд╣реИ, рдкреБрдирд░реНрд╕реНрдерд╛рдкрд┐рдд рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдПрдиреНрдХреНрд░рд┐рдкреНрдЯ рдХрд░рддрд╛ рд╣реИред рд╕рддреНрд░ рдЪрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕рддреНрд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

 session.clear //   session("userId") = 1 //   session.isDefinedAt("userId") //   session("userId") //    


рдлрд┐рд▓реНрдЯрд░



рдлрд╝рд┐рд▓реНрдЯрд░ рдХреЗ рдЙрдкрдпреЛрдЧ рд╕реЗ рдЕрдиреБрд░реЛрдз рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рдФрд░ рдЕрдзрд┐рдХ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдХреБрд▓ рдореЗрдВ рддреАрди рд╣реИрдВ: рдлрд╝рд┐рд▓реНрдЯрд░ рд╕реЗ рдкрд╣рд▓реЗ , рдлрд╝рд┐рд▓реНрдЯрд░ рдФрд░ рдЙрд╕рдХреЗ рдмрд╛рдж рдлрд╝рд┐рд▓реНрдЯрд░ ред рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рдХрд┐рд╕реА рднреА рд░рд┐рдХреНрд╡реЗрд╕реНрдЯ рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рд╕реЗ рдкрд╣рд▓реЗ рдлрд╛рдЗрдЯрд░ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдП, рдпрджрд┐ рд╡рд╣ рдЧрд▓рдд рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдЗрд╕ рдХрдВрдЯреНрд░реЛрд▓рд░ рджреНрд╡рд╛рд░рд╛ рд░рд┐рдХреНрд╡реЗрд╕реНрдЯ рдХреА рдХреЛрдИ рдФрд░ рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рдирд╣реАрдВ рдХреА рдЬрд╛рдПрдЧреАред рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд, afterFilters рдЕрдВрддрд┐рдо рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред

 before1 -true-> before2 -true-> +--------------------+ --> after1 --> after2 | around1 (1 of 2) | | around2 (1 of 2) | | action | | around2 (2 of 2) | | around1 (2 of 2) | +--------------------+ 

рдЙрджрд╛рд╣рд░рдг, рдЕрдиреБрд░реЛрдз рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдПрдХ рдЕрдВрддрд░реНрд░рд╛рд╖реНрдЯреНрд░реАрдпрдХрд░рдг рднрд╛рд╖рд╛ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдирд╛ред

 beforeFilter { val lango: Option[String] = yourMethodToGetUserPreferenceLanguageInSession() lango match { case None => autosetLanguage("ru", "en") case Some(lang) => setLanguage(lang) } true } def execute() { ... } 


рдХреИрд╢рд┐рдВрдЧ



рдЗрд╕рд▓рд┐рдП, рдЕрдиреБрд░реЛрдз рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╕рд░рд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ: (1) рдЕрдиреБрд░реЛрдз -> (2) рдлрд╝рд┐рд▓реНрдЯрд░ рд╕реЗ рдкрд╣рд▓реЗ -> (3) рдлрд╝рд┐рд▓реНрдЯрд░ рдХреЗ рдмрд╛рдж рдирд┐рдпрдВрддреНрд░рдХ рд╡рд┐рдзрд┐ -> (4) рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░реЗрдВ -> (5) рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ред Xitrum рдореЗрдВ CachePageMinute рдПрдиреЛрдЯреЗрд╢рди рдФрд░ рд╕реАрдзреЗ (3) рдореЗрдердб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рдВрдкреВрд░реНрдг рдЕрдиреБрд░реЛрдз рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рдЪреЗрди (2 - 3 - 4 - 5) рдХреЛ рдХреИрд╢ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдХреНрд╖рдорддрд╛рдПрдВ рд╣реИрдВ, - CacheActionMinute рдПрдиреЛрдЯреЗрд╢рдиред рдХреИрд╢ рдЬреАрд╡рдирдХрд╛рд▓ рдорд┐рдирдЯреЛрдВ рдореЗрдВ рдЗрдВрдЧрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдХреЗрд╡рд▓ 200 рдУрдХреЗ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЗ рд╕рд╛рде рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рдПрдВ рдХреИрд╢ рдореЗрдВ рдорд┐рд▓рддреА рд╣реИрдВред

 import xitrum.Action import xitrum.annotation.{GET, CacheActionMinute, CachePageMinute} @GET("articles") @CachePageMinute(1) class ArticlesIndex extends Action { def execute() { ... } } @GET("articles/:id") @CacheActionMinute(10) class ArticlesShow extends Action { def execute() { ... } } 

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

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

 import xitrum.Config.xitrum.cache // Cache with a prefix val prefix = "articles/" + article.id cache.put(prefix + "/likes", likes) cache.put(prefix + "/comments", comments) // Later, when something happens and you want to remove all cache related to the article cache.remove(prefix) 


рдХреИрд╢ рдСрдмреНрдЬреЗрдХреНрдЯ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рджрд╛рди рдХреА рдЧрдИ рд╡рд┐рдзрд┐рдпрд╛рдБ


рд░реЗрд╕реНрдЯрдлреБрд▓ рдПрдкреАрдЖрдИ



рд╕реНрдкрд╖реНрдЯ рд░реВрдЯрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, RESTful API рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рддреБрдЪреНрдЫ рд╣реИред рд╕реНрд╡реИрдЧрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рдорд░реНрдерд┐рдд рдмреЙрдХреНрд╕ рдПрдкреАрдЖрдИ рдкреНрд░рд▓реЗрдЦрди рдореЗрдВ рд╕реЗ

 import xitrum.{Action, SkipCsrfCheck} import xitrum.annotation.{GET, Swagger} @Swagger( Swagger.Note("Dimensions should not be bigger than 2000 x 2000") Swagger.OptStringQuery("text", "Text to render on the image, default: Placeholder"), Swagger.Response(200, "PNG image"), Swagger.Response(400, "Width or height is invalid or too big") ) trait ImageApi extends Action with SkipCsrfCheck { lazy val text = paramo("text").getOrElse("Placeholder") } @GET("image/:width/:height") @Swagger( // <--   ImageApi Swagger.Summary("Generate rectangle image"), Swagger.IntPath("width"), Swagger.IntPath("height") ) class RectImageApi extends Api { def execute { val width = param[Int]("width") val height = param[Int]("height") // ... } } @GET("image/:width") @Swagger( // <--   ImageApi Swagger.Summary("Generate square image"), Swagger.IntPath("width") ) class SquareImageApi extends Api { def execute { val width = param[Int]("width") // ... } } 

рд░рди рд╕рдордп рдореЗрдВ, xitrum swagger.json рдЙрддреНрдкрдиреНрди рдХрд░реЗрдЧрд╛ рдЬреЛ рд╕реНрд╡реИрдЧрд░ UI рдореЗрдВ рдЖрд╕рд╛рдиреА рд╕реЗ рдкреНрд░рд▓реЗрдЦрди рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдорд╣рддреНрд╡рдкреВрд░реНрдг : рд╕рднреА POST рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рд▓рд┐рдП, CSRF рд╣рдорд▓реЛрдВ рд╕реЗ рд╕реБрд░рдХреНрд╖рд╛ рдкреНрд░рджрд╛рди рдХреА рдЬрд╛рддреА рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЖрдкрдХреЛ рдХрд┐рд╕реА рднреА POST рдЕрдиреБрд░реЛрдз рдХреЗ рд╕рд╛рде csrf-token рдкрд╛рд╕ рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдпрд╛ SkipCsrfCheck рд╡рд┐рд╢реЗрд╖рддрд╛ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕ рд╕реБрд░рдХреНрд╖рд╛ рдХреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЕрдХреНрд╖рдо рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рд╕реАрдПрд╕рдЖрд░рдПрдл-рдЯреЛрдХрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдиреЗрдВред

рдЕрдВрддрд░реНрд░рд╛рд╖реНрдЯреНрд░реАрдпрдХрд░рдг
рдЬреАрдПрдирдпреВ рдЧреЗрдЯрдЯреЗрдХреНрд╕реНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдВрддрд░реНрд░рд╛рд╖реНрдЯреНрд░реАрдпрдХрд░рдг рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдирд┐рдпрдВрддреНрд░рдХ рдореЗрдВ рдЕрдВрддрд░реНрд░рд╛рд╖реНрдЯреНрд░реАрдпрдХрд░рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рдзрд┐ рд╣реИ ред

 def execute() { respondHtml(t("hello_world")) } 

рд╡рд░реНрддрдорд╛рди рдЕрдиреБрд╡рд╛рдж рднрд╛рд╖рд╛ рдХреЛ рд╕реЗрдЯ рд▓реИрдВрдЧреНрд╡реЗрдЬ рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЪреБрдирд╛ рдЧрдпрд╛ рд╣реИ; рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЖрдк рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдПрдХреНрд╕реЗрдкреНрдЯ-рд▓реИрдВрдЧреНрд╡реЗрдЬ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдХрд┐рд╕реА рднрд╛рд╖рд╛ рдХрд╛ рд╕реНрд╡рддрдГ рдЪрдпрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдСрдЯреЛрд╕реЗрдЯрд▓реЗрдВрдЧреЗрдЬ рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдкреЙрдЯ рдЯреЗрдореНрдкрд▓реЗрдЯ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ sbt рд╕рдВрдХрд▓рди рдЪрд▓рд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЕрдиреБрд╡рд╛рдж рдХреЗ рд╕рд╛рде рдлрд╛рдЗрд▓ рдХреЛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЗ рдХреНрд▓рд╛рд╕рдкрд╛рде рдореЗрдВ рд░рдЦрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП (рдЖрдорддреМрд░ рдкрд░ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди / i18n рдореЗрдВ)ред рдпрджрд┐ рд╕рд░реНрд╡рд░ рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдХреЗ рджреМрд░рд╛рди рдЕрдиреБрд╡рд╛рдж рдХреЗ рд╕рд╛рде рдлрд╛рдЗрд▓ рдХреЛ рдмрджрд▓ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рддреЛ рдЗрд╕реЗ рдлрд┐рд░ рд╕реЗ рдкрдврд╝рд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рд╕рд░реНрд╡рд░ рдХреЛ рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рдХрд┐рдП рдмрд┐рдирд╛ рдЕрдиреБрд╡рд╛рдж рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред


рдпрджрд┐ рдЖрдк рдЗрд╕ рд▓реЗрдЦ рдХреЛ рдЕрдВрдд рддрдХ рдкрдврд╝рддреЗ рд╣реИрдВ, рддреЛ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЕрдм рдЖрдк рдврд╛рдВрдЪреЗ рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ 70% рдЬрд╛рдирддреЗ рд╣реИрдВред рдФрд░ рдпрд╣ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореЗрд░реЗ рд╡рд┐рдЪрд╛рд░ рдХреА рдкреБрд╖реНрдЯрд┐ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдкреНрд░рд╡реЗрд╢ рд╕реАрдорд╛ рдмрд╣реБрдд рдХрдо рд╣реИред рдЗрд╕рд▓рд┐рдП, рдореИрдВ рд╕реБрдЭрд╛рд╡ рджреЗрдиреЗ рдФрд░ рд╕рд╡рд╛рд▓ рдкреВрдЫрдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВред

рдЖрдк рдкрд╛рдареНрдпрдкреБрд╕реНрддрдХ рдореЗрдВ рд╣рдореЗрд╢рд╛ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рд╡реЗрдмрд╕рд╛рдЗрдЯ рдкрд░ рдмрд╛рдХреА рд╕рд╛рдордЧреНрд░реА рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВред рдкреНрд░рд╢реНрди рдЬреЛ рдореИрдВ рдмрддрд╛рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛:


рд╕реВрддреНрд░реЛрдВ рдХрд╛ рдХрд╣рдирд╛ рд╣реИ


рдбреЗрдореЛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ
рдПрдХ рдореБрдЦреНрдп рдкрд░рд┐рдпреЛрдЬрдирд╛ рдЬреЛ рджрд┐рдЦрд╛ рд░рд╣реА рд╣реИ рдХрд┐ рдПрдХреНрд╕рдЯреНрд░рдо рдХрд┐рд╕рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реИ (рдпрд╣ рдкреНрд░рд╢рд┐рдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЙрдкрдпреЛрдЧреА рдирд╣реАрдВ рд╣реИ):
 git clone https://github.com/ngocdaothanh/xitrum-demos.git cd xitrum-demos sbt/sbt run 

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


All Articles