рдкрд┐рдЫрд▓реЗ рд╣рдлреНрддреЗ рд╣реИрдмреЗ рдкрд░ рдЬрд╛рд╡рд╛ рдореЗрдВ рд░реЗрд╕реНрдЯрдлреБрд▓ рд╡реЗрдм-рд╕реЗрд╡рд╛рдУрдВ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкрд░ рджреЛ рд▓реЗрдЦ рдХреЗ рд░реВрдк рдореЗрдВ рдХрдИ рдереЗред рдареАрдХ рд╣реИ, рдЪрд▓реЛ рдкреАрдЫреЗ рдирд╣реАрдВ рд░рд╣рддреЗ рд╣реИрдВ рдФрд░ рд╕реНрдХреЗрд▓рд╛ рдкрд░ рдЕрдкрдирд╛ рд╕реНрд╡рдпрдВ рдХрд╛ рд╕рдВрд╕реНрдХрд░рдг рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рднрд┐рдХреНрд╖реБрдУрдВ рдФрд░ рдЖрд╡реЗрджрдХ рдХреЗ рд╕рд╛рдеред рдЕрдиреБрднрд╡реА рд╕реНрдХрд╛рд▓рд╛ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЛ рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдХреБрдЫ рднреА рдирдпрд╛ рдорд┐рд▓рдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдирд╣реАрдВ рд╣реИ, рдФрд░ Django рдХреЗ рдкреНрд░рд╢рдВрд╕рдХ рдЖрдорддреМрд░ рдкрд░ рдХрд╣реЗрдВрдЧреЗ рдХрд┐ рдЙрдирдХреЗ рдкрд╛рд╕ рдпрд╣ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдмреЙрдХреНрд╕ рд╕реЗ рдмрд╛рд╣рд░ рд╣реИ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЬрд╛рд╡рд╛ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд▓рд┐рдП рджрд┐рд▓рдЪрд╕реНрдк рд╣реЛрдЧрд╛ рдФрд░ рд╕рд┐рд░реНрдл рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрддреНрд╕реБрдХ рд╣реЛрдЧрд╛ред
рдЯреНрд░реЗрдирд┐рдВрдЧ
рд╣рдо
рдкрд┐рдЫрд▓реЗ рд▓реЗрдЦ рд╕реЗ рдЖрдзрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рд░реНрдп рд▓реЗрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╣рдо рдЗрд╕реЗ рд╣рд▓ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВрдЧреЗ рддрд╛рдХрд┐ рд╕рдорд╛рдзрд╛рди рдХреЛрдб рд╕реНрдХреНрд░реАрди рдкрд░ рдлрд┐рдЯ рд╣реЛ рдЬрд╛рдПред рдХрдо рд╕реЗ рдХрдо 40 рдЗрдВрдЪ рдФрд░ рдкрд╛рдВрдЪрд╡рд╛рдВ рдлрд╝реЙрдиреНрдЯред рдЕрдВрдд рдореЗрдВ, 21 рд╡реАрдВ рд╕рджреА рдореЗрдВ, xml-configs рдФрд░ рджрд░реНрдЬрдиреЛрдВ рдЕрдореВрд░реНрдд рдХрд╛рд░рдЦрд╛рдиреЛрдВ рдХреЗ рдореЗрдЧрд╛рдмрд╛рдЗрдЯ рдХреЗ рдмрд┐рдирд╛ рд╕рд░рд▓ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд╣рд▓ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
рдЬреЛ рд▓реЛрдЧ рд▓рд┐рдВрдХ рдХрд╛ рдкрд╛рд▓рди рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдореИрдВ рд╕реНрдкрд╖реНрдЯ рдХрд░рддрд╛ рд╣реВрдВ: рд╣рдо рдЧреНрд░рд╛рд╣рдХ рдбреЗрдЯрд╛рдмреЗрд╕ рддрдХ рдкрд╣реБрдБрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдмрд╕реЗ рд╕рд░рд▓ рд╕реЗрд╡рд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВред рдЖрд╡рд╢реНрдпрдХ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдореЗрдВ рд╕реЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдФрд░ рд╡рд┐рд▓реЛрдкрди рд╣реИ, рд╕рд╛рде рд╣реА рд╕рд╛рде рд╡рд┐рднрд┐рдиреНрди рдХреНрд╖реЗрддреНрд░реЛрдВ рджреНрд╡рд╛рд░рд╛ рд╕реЙрд░реНрдЯ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рд╡рд╛рд▓реЗ рд╕рднреА рдХреНрд▓рд╛рдЗрдВрдЯ рдХреА рд╕реВрдЪреА рдХрд╛ рдкреЗрдЬрд┐рдиреЗрд╢рди рднреА рд╣реИред
рдИрдВрдЯреЗрдВ рдЬрд┐рд╕рд╕реЗ рд╣рдо рдПрдХ рдШрд░ рдмрдирд╛рдПрдВрдЧреЗ, рд╣рдо рд▓реЗрддреЗ рд╣реИрдВ:
- рд╕реНрдХрд╛рд▓рд╛ рдПрдХ рдИрдВрдЯ рднреА рдирд╣реАрдВ рд╣реИ, рдмрд▓реНрдХрд┐ рдПрдХ рдиреАрдВрд╡ рд╣реИ,
- рдЕрдирдлрд╝рд┐рд▓реНрдЯрд░реНрдб HTTP рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдорд╣рд╛рди рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╣реИ,
- Squeryl - рдбреЗрдЯрд╛рдмреЗрд╕ рдкреНрд░рд╢реНрдиреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп,
- рдЬреИрдХреНрд╕рди JSON рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╣реИ, рдЬреЛ рдореВрд▓ рд░реВрдк рд╕реЗ рдЬрд╛рд╡рд╛ рдХреЗ рд▓рд┐рдП рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рдзрдорд╛рдХреЗ рдХреЗ рд╕рд╛рде рдпрд╣ рд╕реНрдХрд╛рд▓рд╛ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рдореБрдХрд╛рдмрд▓рд╛ рдХрд░рддрд╛ рд╣реИ,
- рд╕реНрдХреИрд▓рд╛рдЬрд╝ рдПрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╣реИ рдЬреЛ рдЖрдкрдХреЛ тЖж, library, рдпрд╛ тИГ рдЬреИрд╕реЗ рдХреЛрдб рдореЗрдВ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдордЬрд╝реЗрджрд╛рд░ рдЪрд░рд┐рддреНрд░ рд▓рд┐рдЦрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдФрд░ рд╕рд╛рде рд╣реА рд╕рд╛рде рдЙрдкрдпреЛрдЧреА рдЙрдкрд╛рджрд╛рдиреЛрдВ рдЬреИрд╕реЗ рдХрд┐ рдРрдкреНрд▓рд┐рдХреЗрдЯрд┐рд╡ рдлрд╝рдВрдХреНрд╢рдВрд╕, рдореЛрдиреЙрдпрдбреНрд╕, рд╕реЗрдореАрдЧреНрд░реБрдкреНрд╕ рдФрд░ рдХреНрд▓реЗрдпрд░рд▓реА рдПрд░реЛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред рд╕рдЪ рд╣реИ, рдореБрдЭреЗ рдЕрднреА рддрдХ рдЙрддреНрддрд░рд╛рд░реНрджреНрдз рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рдирд╛ рдкрдбрд╝рд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдЗрд╕ рддрдереНрдп рдХреЗ рдХрд╛рд░рдг рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ рдХрд┐ рдореИрдВ рдЕрднреА рддрдХ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдЬреНрдЮрд╛рди рдХреА рдЖрд╡рд╢реНрдпрдХ рдбрд┐рдЧреНрд░реА рддрдХ рдирд╣реАрдВ рдкрд╣реБрдВрдЪ рдкрд╛рдпрд╛ рд╣реВрдВред
рд▓реЗрдЦ рдХреЗ рдкрд╛рдареНрдпрдХреНрд░рдо рдореЗрдВ, рдореИрдВ рдкрд░реНрдпрд╛рдкреНрдд рд╕реНрдкрд╖реНрдЯреАрдХрд░рдг рджреЗрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реВрдВрдЧрд╛ рддрд╛рдХрд┐ рдХреЛрдб рдХреЛ рд╕реНрдХрд╛рд▓рд╛ рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рд▓реЛрдЧреЛрдВ рджреНрд╡рд╛рд░рд╛ рд╕рдордЭрд╛ рдЬрд╛ рд╕рдХреЗ, рд▓реЗрдХрд┐рди рдореИрдВ рд╡рд╛рджрд╛ рдирд╣реАрдВ рдХрд░рддрд╛ рдХрд┐ рдХреНрдпрд╛ рдХрд╛рдо рдХрд░реЗрдЧрд╛ред
рд▓рдбрд╝рд╛рдИ рдореЗрдВ
рдбреЗрдЯрд╛ рдореЙрдбрд▓
рдкрд╣рд▓реЗ рд╣рдореЗрдВ рдПрдХ рдбреЗрдЯрд╛ рдореЙрдбрд▓ рдкрд░ рдирд┐рд░реНрдгрдп рд▓реЗрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рд╕реНрдХреНрд╡реЗрд░реАрд▓ рдЖрдкрдХреЛ рдПрдХ рдирд┐рдпрдорд┐рдд рд╡рд░реНрдЧ рдХреЗ рд░реВрдк рдореЗрдВ рдореЙрдбрд▓ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдФрд░ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдирд╣реАрдВ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо JSON рдореЗрдВ рдмрд╛рдж рдХреЗ рдХреНрд░рдорд╛рдВрдХрди рдХреЗ рд▓рд┐рдП рдЙрд╕реА рд╡рд░реНрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред
@JsonIgnoreProperties(Array("_isPersisted")) case class Customer(id: String, firstName: String, lastName: String, email: Option[String], birthday: Option[Date]) extends KeyedEntity[String]
рдкреНрд░рдХрд╛рд░ рдХреЗ
Option[_]
рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рдЕрд╢рдХреНрдд рд╕реНрддрдВрднреЛрдВ рдХреЗ рдЕрдиреБрд░реВрдк рд╣реИрдВред рдРрд╕реЗ рдлрд╝реАрд▓реНрдб рджреЛ рдкреНрд░рдХрд╛рд░ рдХреЗ рдорд╛рди рд▓реЗ рд╕рдХрддреЗ рд╣реИрдВ:
Some(value)
, рдпрджрд┐ рдХреЛрдИ рдорд╛рди рд╣реИ, рдФрд░
None
, рдпрджрд┐ рдпрд╣ рдирд╣реАрдВ рд╣реИред
Option
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдЖрдк
NullPointerException
рдХреА рд╕рдВрднрд╛рд╡рдирд╛рдУрдВ рдХреЛ рдХрдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рдПрдХ рдЖрдо рдмрд╛рдд рд╣реИ (рд╡рд┐рд╢реЗрд╖рдХрд░ рдЙрди рдЬрд┐рдирдореЗрдВ рдХреЛрдИ
null
рдЕрд╡рдзрд╛рд░рдгрд╛ рдирд╣реАрдВ рд╣реИ)ред
@JsonIgnoreProperties
JSON рдХреНрд░рдорд╛рдВрдХрди рд╕реЗ рдХреБрдЫ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЛ рдмрд╛рд╣рд░ рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ,
_isPersisted
рдлрд╝реАрд▓реНрдб рдХреЛ рдмрд╛рд╣рд░ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдерд╛, рдЬрд┐рд╕реЗ рд╕реНрдХреНрд╡реЗрдпрд░ рдиреЗ рдЬреЛрдбрд╝рд╛ред
рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реНрдХреАрдорд╛ рдХреА рд╢реБрд░реБрдЖрдд
рдЬрд┐рди рд▓реЛрдЧреЛрдВ рдиреЗ JDBC рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд┐рдпрд╛ рд╣реИ, рд╡реЗ рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдбреНрд░рд╛рдЗрд╡рд░ рдХреНрд▓рд╛рд╕ рдХреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд░рдирд╛ рд╣реИред рдЖрдЗрдП рдЗрд╕ рдЕрднреНрдпрд╛рд╕ рд╕реЗ рд╡рд┐рдЪрд▓рд┐рдд рди рд╣реЛрдВ:
Class.forName("org.h2.Driver") SessionFactory.concreteFactory = Some(() => Session.create(DriverManager.getConnection("jdbc:h2:test", "sa", ""), new H2Adapter))
рдкрд╣рд▓реА рдкрдВрдХреНрддрд┐ рдореЗрдВ, рд╣рдо рдЬреЗрдбреАрдмреАрд╕реА рдбреНрд░рд╛рдЗрд╡рд░ рдХреЛ рд▓реЛрдб рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рджреВрд╕рд░реЗ рдореЗрдВ рд╣рдо рд╕реНрдХреНрд╡реАрд░реА рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛ рдмрддрд╛рддреЗ рд╣реИрдВ рдХрд┐ рдХрд┐рд╕ рдХрд╛рд░рдЦрд╛рдиреЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИред рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд░реВрдк рдореЗрдВ рд╣рдо рдкреНрд░рдХрд╛рд╢ рдФрд░ рддреЗрдЬ
H2 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред
рдЕрдм рдпреЛрдЬрдирд╛ рдХреА рдмрд╛рд░реА рдЖрдИ рд╣реИ:
object DB extends Schema { val customer = table[Customer] } transaction { allCatch opt DB.create }
рдкрд╣рд▓реЗ, рд╣рдо рд╕рдВрдХреЗрдд рджреЗрддреЗ рд╣реИрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рд╣реИ рдЬреЛ
Customer
рд╡рд░реНрдЧ рд╕реЗ рдореЗрд▓ рдЦрд╛рддреА рд╣реИ, рдФрд░ рдлрд┐рд░ рд╣рдо рдЗрд╕ рддрд╛рд▓рд┐рдХрд╛ рдХреЛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП DDL рдХрдорд╛рдВрдб рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддреЗ рд╣реИрдВред рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЬреАрд╡рди рдореЗрдВ, рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдЯреЗрдмрд▓ рдирд┐рд░реНрдорд╛рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдЖрдорддреМрд░ рдкрд░ рд╕рдорд╕реНрдпрд╛рдЧреНрд░рд╕реНрдд рд╣реЛрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рддреНрд╡рд░рд┐рдд рдкреНрд░рджрд░реНрд╢рди рдХреЗ рд▓рд┐рдП рдпрд╣ рдмрд╣реБрдд рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИред рдпрджрд┐ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рддрд╛рд▓рд┐рдХрд╛рдПрдБ рдкрд╣рд▓реЗ рд╕реЗ рдореМрдЬреВрдж рд╣реИрдВ, рддреЛ
DB.create
рдПрдХ рдЕрдкрд╡рд╛рдж
DB.create
рдлреЗрдВрдХ
DB.create
, рдЬрд┐рд╕реЗ рд╣рдо
allCatch opt
рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдЕрдирджреЗрдЦрд╛ рдХрд░реЗрдВрдЧреЗред
JSON рд╕реАрд░рд┐рдпрд▓рд╛рдЗрдЬрд╝реЗрд╢рди рдФрд░ рдбрд┐рд╕реЗрд░рд┐рдПрд▓рд╛рдЗрдЬрд╝реЗрд╢рди
рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, JSON рдкрд╛рд░реНрд╕рд░ рдХреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд░реЗрдВ рддрд╛рдХрд┐ рдпрд╣ рд╕реНрдХреЗрд▓ рдореЗрдВ рд╕реНрд╡реАрдХреГрдд рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд╕рдХреЗ:
val mapper = new ObjectMapper().withModule(DefaultScalaModule)
рдЕрдм рд╣рдо JSON рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдХреЛ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдореЗрдВ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рджреЛ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ:
def parseCustomerJson(json: String): Option[Customer] = allCatch opt mapper.readValue(json, classOf[Customer]) def readCustomer(req: HttpRequest[_], id: => String): Option[Customer] = parseCustomerJson(Body.string(req)) map (_.copy(id = id))
parseCustomerJson
рдлрд╝рдВрдХреНрд╢рди рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ JSON рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░ рд░рд╣рд╛ рд╣реИред
allCatch opt
рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж
allCatch opt
рдкрд╛рд░реНрд╕рд┐рдВрдЧ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рджреМрд░рд╛рди рд╣реЛрдиреЗ
allCatch opt
рдЕрдкрд╡рд╛рдж рдкрдХрдбрд╝реЗ рдЬрд╛рдПрдВрдЧреЗ рдФрд░ рд╣рдореЗрдВ рдкрд░рд┐рдгрд╛рдо рдХреЗ рд░реВрдк рдореЗрдВ
None
рдорд┐рд▓реЗрдЧрд╛ред рджреВрд╕рд░рд╛ рдлрд╝рдВрдХреНрд╢рди,
readCustomer
, рд╕реАрдзреЗ HTTP рдЕрдиреБрд░реЛрдз рдХреЗ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИ - рдпрд╣ рдЕрдиреБрд░реЛрдз рдирд┐рдХрд╛рдп рдХреЛ рдкрдврд╝рддрд╛ рд╣реИ, рдЗрд╕реЗ
Customer
рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рдмрджрд▓ рджреЗрддрд╛ рд╣реИ рдФрд░
id
рдлрд╝реАрд▓реНрдб рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдорд╛рди рдкрд░ рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИред
рдпрд╣ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдХрд┐ рджреЛрдиреЛрдВ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рд░рд┐рдЯрд░реНрди рд╡реИрд▓реНрдпреВ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рдерд╛: рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЗ рдкрд╛рд╕ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдХреА рдорджрдж рдХреЗ рдмрд┐рдирд╛ рдЯрд╛рдЗрдк рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рдбреЗрдЯрд╛ рдерд╛, рд▓реЗрдХрд┐рди рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдкреНрд░рдХрд╛рд░ рдХрднреА-рдХрднреА рдХреЛрдб рдХреА рдорд╛рдирд╡ рд╕рдордЭ рдХреА рд╕реБрд╡рд┐рдзрд╛ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред
рдЙрд▓рдЯреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ - HTTP рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЗ рд╢рд░реАрд░ рдореЗрдВ
Customer
рд╡рд╕реНрддреБ (рдпрд╛
List[Customer]
рд╕реВрдЪреА) рдХреЛ рдмрджрд▓рдирд╛ - рднреА рдореБрд╢реНрдХрд┐рд▓ рдирд╣реАрдВ рд╣реИ:
case class ResponseJson(o: Any) extends ComposeResponse( ContentType("application/json") ~> ResponseString(mapper.writeValueAsString(o)))
рднрд╡рд┐рд╖реНрдп рдореЗрдВ, рд╣рдо рдХреЗрд╡рд▓
ResponseJson
рдкреНрд░рдХрд╛рд░ рдХреА рд╡рд╕реНрддреБрдУрдВ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░реЗрдВрдЧреЗ, рдФрд░ рдЕрдирдлрд╝рд┐рд▓реНрдЯрд░реНрдб рдлрд╝реНрд░реЗрдорд╡рд░реНрдХ рдЗрд╕реЗ рд╕рд╣реА HTTP рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдмрджрд▓рдиреЗ рдХрд╛ рдзреНрдпрд╛рди рд░рдЦреЗрдЧрд╛ред
рдПрдХ рдФрд░ рдЫреЛрдЯрд╛ рд╕реНрдкрд░реНрд╢ рдирдП рдЧреНрд░рд╛рд╣рдХ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛рдУрдВ рдХреА рдкреАрдврд╝реА рд╣реИред рд╕рдмрд╕реЗ рдЖрд╕рд╛рди, рд╣рд╛рд▓рд╛рдВрдХрд┐ рд╣рдореЗрд╢рд╛ рд╕рдмрд╕реЗ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИ, рдпреВрдпреВрдЖрдИрдбреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИ:
def nextId = UUID.randomUUID().toString
HTTP рдЕрдиреБрд░реЛрдз рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг
рдЕрдм рдЬрдмрдХрд┐ рдЕрдзрд┐рдХрд╛рдВрд╢ рддреИрдпрд╛рд░реА рдХрд╛рд░реНрдп рд╣реЛ рдЪреБрдХреЗ рд╣реИрдВ, рд╣рдо рд╕реАрдзреЗ рд╡реЗрдм рд╕реЗрд╡рд╛ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ рдмрдврд╝ рд╕рдХрддреЗ рд╣реИрдВред рдореИрдВ рдЕрдирдлрд┐рд▓реНрдЯрд░реНрдб рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рд╡рд┐рд╡рд░рдг рдореЗрдВ рдирд╣реАрдВ рдЬрд╛рдКрдВрдЧрд╛, рдореИрдВ рд╕рд┐рд░реНрдл рдЗрддрдирд╛ рдХрд╣реВрдВрдЧрд╛ рдХрд┐ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рд╕рд░рд▓ рддрд░реАрдХрд╛ рд╣реИ:
val service = cycle.Planify { case => }
рд╣рдорд╛рд░реА рд╕реЗрд╡рд╛ рдореЗрдВ рджреЛ рдкреНрд░рд╡реЗрд╢ рдмрд┐рдВрджреБ рд╣реЛрдВрдЧреЗ:
/customer
рдФрд░
/customer/[id]
ред рдЪрд▓реЛ рджреВрд╕рд░реЗ рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ:
case req@Path(Seg("customer" :: id :: Nil)) => req match { case GET(_) => transaction { DB.customer.lookup(id) cata(ResponseJson, NotFound) } case PUT(_) => transaction { readCustomer(req, id) тИШ DB.customer.update cata(_ => Ok, BadRequest) } case DELETE(_) => transaction { DB.customer.delete(id); NoContent } case _ => Pass }
рдкрд╣рд▓реА рдкрдВрдХреНрддрд┐ рдореЗрдВ, рд╣рдо рдпрд╣ рд╕рдВрдХреЗрдд рджреЗрддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рдХреЛрдб рдХреЗрд╡рд▓ рдлреЙрд░реНрдо
/customer/[id]
URL рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИ рдФрд░ рдкрд╛рд░рд┐рдд рдХрд┐рдП рдЧрдП рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдХреЛ рдЖрдИрдбреА рдЪрд░ рдореЗрдВ рдмрд╛рдБрдзрддрд╛ рд╣реИ (рдпрджрд┐ рдЕрдкрд░рд┐рд╡рд░реНрддрдиреАрдп рдЪрд░ рдХреЛ рдХрд╣рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ)ред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкрдВрдХреНрддрд┐рдпреЛрдВ рдореЗрдВ, рд╣рдо рдЕрдиреБрд░реЛрдз рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдкрд░рд┐рд╖реНрдХреГрдд рдХрд░рддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЪрд░рдгреЛрдВ рдореЗрдВ PUT рд╡рд┐рдзрд┐ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреА рдЬрд╛рдБрдЪ рдХрд░рддреЗ рд╣реИрдВ:
transaction { ... }
: рд╣рдо рд╕рдВрдХреЗрдд рджреЗрддреЗ рд╣реИрдВ рдХрд┐ рд╣реИрдВрдбрд▓рд░ рдХреЗ рд╢рд░реАрд░ рдХреА рдЕрд╡рдзрд┐ рдХреЗ рд▓рд┐рдП, рдПрдХ рд▓реЗрдирджреЗрди рдЦреЛрд▓рд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП,readCustomer(req, id)
: рдкреВрд░реНрд╡ рд▓рд┐рдЦрд┐рдд рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ рдЬреЛ рдЕрдиреБрд░реЛрдз рдирд┐рдХрд╛рдп рдФрд░ рд░рд┐рдЯрд░реНрди Option[Customer]
рдкрдврд╝рддрд╛ рд╣реИ Option[Customer]
тИШ
: рдпрд╣ рдкреНрд░рддреАрдХ рд╡рд┐рд╢реЗрд╖ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣ рдорд╛рдирдЪрд┐рддреНрд░ рд╕рдВрдЪрд╛рд▓рди рдХрд╛ рдПрдХ рдкрд░реНрдпрд╛рдп рд╣реИ рдФрд░ рдЖрдкрдХреЛ рд╡рд┐рдХрд▓реНрдк рд╕рд╛рдордЧреНрд░реА рдХреЗ рд▓рд┐рдП рдХреБрдЫ рдлрд╝рдВрдХреНрд╢рди рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдпрджрд┐ рдпрд╣ рд╕рд╛рдордЧреНрд░реА рд╣реИ;DB.customer.update
: рдЬрд┐рд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╣рдо рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рд╡рд╣ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдЗрдХрд╛рдИ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░ рд░рд╣рд╛ рд╣реИ,cata(_ => Ok, BadRequest)
: рдпрджрд┐ Option
рдХрд╛ рдХреЛрдИ рдореВрд▓реНрдп рдирд╣реАрдВ рд╣реИ рдпрд╛ рдирд╣реАрдВ рддреЛ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЗ рдмрдЬрд╛рдп рд╣рдорд╛рд░реЗ рдкрд╛рд╕ None
рдЕрдЧрд░ Option
рдХрд╛ рдХреЛрдИ рдореВрд▓реНрдп рдпрд╛ BadRequest
рддреЛ Ok
ред
GET рдФрд░ DELETE рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд╕рдорд╛рди рд░реВрдк рд╕реЗ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
/customer
рд╕реЗ рдЕрдиреБрд░реЛрдз рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рд╣реИрдВрдбрд▓рд░ рдХреА рджреВрд╕рд░реА рдЫрдорд╛рд╣реА рдореЗрдВ, рд╣рдореЗрдВ рджреЛ рд╕рд╣рд╛рдпрдХ рдХрд╛рд░реНрдпреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА:
val field: PartialFunction[String, Customer => TypedExpressionNode[_]] = { case "id" => _.id case "firstName" => _.firstName case "lastName" => _.lastName case "email" => _.email case "birthday" => _.birthday } val ordering: PartialFunction[String, TypedExpressionNode[_] => OrderByExpression] = { case "asc" => _.asc case "desc" => _.desc }
рдЗрди рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдЕрдиреБрд░реЛрдз рдХреЗ рд╣рд┐рд╕реНрд╕реЗ
order by
рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░, рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ, рд╕реНрдХреНрд╡реЗрд░реАрд▓ рдХреЗ рдЖрдВрддреЛрдВ рдореЗрдВ рдЕрдлрд╡рд╛рд╣ рдХрд░рддреЗ рд╣реБрдП, рдЙрдиреНрд╣реЗрдВ рдЖрд╕рд╛рди рд▓рд┐рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕ рд╡рд┐рдХрд▓реНрдк рдиреЗ рднреА рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдХрд┐рдпрд╛ред рд╣реИрдВрдбрд▓рд░ рдХреЛрдб рд╣реА:
case req@Path(Seg("customer" :: Nil)) => req match { case POST(_) => transaction { readCustomer(req, nextId) тИШ DB.customer.insert тИШ ResponseJson cata(_ ~> Created, BadRequest) } case GET(_) & Params(params) => transaction { import Params._ val orderBy = (params.get("orderby") тИЧ first orElse Some("id")) тИЧ field.lift val order = (params.get("order") тИЧ first orElse Some("asc")) тИЧ ordering.lift val pageNum = params.get("pagenum") тИЧ (first ~> int) val pageSize = params.get("pagesize") тИЧ (first ~> int) val offset = ^(pageNum, pageSize)(_ * _) val query = from(DB.customer) { q => select(q) orderBy ^(orderBy, order)(_ andThen _ apply q).toList } val pagedQuery = ^(offset, pageSize)(query.page) getOrElse query ResponseJson(pagedQuery.toList) } case _ => Pass }
POST рдЕрдиреБрд░реЛрдз рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣рд┐рд╕реНрд╕рд╛ рдХреБрдЫ рдирдпрд╛ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдлрд┐рд░ рд╣рдореЗрдВ рдЕрдиреБрд░реЛрдз рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдФрд░ рджреЛ рдЕрд╕реНрдкрд╖реНрдЯ рд╡рд░реНрдг рджрд┐рдЦрд╛рдИ рджреЗрдВрдЧреЗ: characters рдФрд░
^
ред рдкрд╣рд▓рд╛ (рдзреНрдпрд╛рди рд╕реЗ, рд╕рд╛рдорд╛рдиреНрдп рддрд╛рд░рд╛рдВрдХрди рдХреЗ рд╕рд╛рде рдЗрд╕реЗ рднреНрд░рдорд┐рдд рди рдХрд░реЗрдВ)
*
flatMap
рдХрд╛ рдПрдХ рдкрд░реНрдпрд╛рдп рд╣реИ рдФрд░
map
рд╕реЗ рдЕрд▓рдЧ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рдлрд╝рдВрдХреНрд╢рди рдХреЛ рднреА
Option
рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдо рдХреНрд░рдорд┐рдХ рд░реВрдк рд╕реЗ рдХрдИ рдСрдкрд░реЗрд╢рди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд┐рдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдпрд╛ рддреЛ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдПрдХ рдореВрд▓реНрдп рджреЗрддрд╛ рд╣реИ рдпрд╛ рддреНрд░реБрдЯрд┐ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ
None
рд▓реМрдЯрд╛рддрд╛ рд╣реИред рджреВрд╕рд░рд╛ рдСрдкрд░реЗрдЯрд░ рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реИ рдФрд░ рдЖрдкрдХреЛ рдХреБрдЫ рдСрдкрд░реЗрд╢рди рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдХреЗрд╡рд▓ рддрднреА рджреЗрддрд╛ рд╣реИ рдЬрдм рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рд╕рднреА рдЪрд░ рдХрд┐рд╕реА рдХреЗ рдмрд░рд╛рдмрд░
None
ред рдпрд╣ рд╣рдореЗрдВ рдХреЗрд╡рд▓ рддрднреА рд╕реЙрд░реНрдЯ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдЬрдм рд╕реНрддрдВрдн рдФрд░ рджрд┐рд╢рд╛ рджреЛрдиреЛрдВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдФрд░ рдкрд░рд┐рдгрд╛рдо рдХреЛ рдкреГрд╖реНрдареЛрдВ рдореЗрдВ рддрдм рд╣реА рддреЛрдбрд╝рддреЗ рд╣реИрдВ рдЬрдм рдкреГрд╖реНрда рд╕рдВрдЦреНрдпрд╛ рдФрд░ рдЙрд╕рдХрд╛ рдЖрдХрд╛рд░ рджреЛрдиреЛрдВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рд╣реЛрддреЗ рд╣реИрдВред
рдпрд╣ рд╕рдм рд╣реИ, рдЬреЛ рд╕рднреА рд░рд╣рддрд╛ рд╣реИ рд╡рд╣ рд╕рд░реНрд╡рд░ рдХреЛ рд╢реБрд░реВ рдХрд░рдирд╛ рд╣реИ
Http(8080).plan(service).run()
рдФрд░ рдЖрдк рдХрд░реНрд▓ рдЙрдард╛ рд╕рдХрддреЗ рд╣реИрдВ рдпрд╣ рдЬрд╛рдВрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рд╕рдм рдХреБрдЫ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред
рдирд┐рд╖реНрдХрд░реНрд╖
рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рдкрд░рд┐рдгрд╛рдореА рд╡реЗрдм рд╕реЗрд╡рд╛ рдХреЛрдб рдХреЙрдореНрдкреИрдХреНрдЯ рдФрд░ рдкрдврд╝рдиреЗ рдореЗрдВ рдХрд╛рдлреА рдЖрд╕рд╛рди рд╣реИ, рдФрд░ рдпрд╣ рдПрдХ рдмрд╣реБрдд рд╣реА рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╕рдВрдкрддреНрддрд┐ рд╣реИред рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд░реВрдк рд╕реЗ, рдпрд╣ рдЖрджрд░реНрд╢ рдирд╣реАрдВ рд╣реИ: рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рд╢рд╛рдпрдж
scala.Either
рдпрд╛
scalaz.Validation
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╕рд╛рд░реНрдердХ рдерд╛, рд▓реЗрдХрд┐рди рдХреЛрдИ рдпреВрдирд┐рдХреЛрдб рдСрдкрд░реЗрдЯрд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдкрд╕рдВрдж рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдмрд╛рд╣рд░реА рд╕рд╛рджрдЧреА рдХреЗ рдкреАрдЫреЗ, рдХрднреА-рдХрднреА рдХрд╛рдлреА рдЬрдЯрд┐рд▓ рд╕рдВрдЪрд╛рд▓рди рдЫрд┐рдкрд╛рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдпрд╣ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ "рд╣реБрдб рдХреЗ рддрд╣рдд" рд╕рдм рдХреБрдЫ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ "рдЖрдкрдХреЛ рдЧрд╛рдЗрд░рд╕ рдХреЛ рддрдирд╛рд╡ рджреЗрдирд╛ рд╣реЛрдЧрд╛ред рдлрд┐рд░ рднреА, рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрд╣ рд▓реЗрдЦ рдХрд┐рд╕реА рдХреЛ рд╕реНрдХрд╛рд▓рд╛ рдкрд░ рдХрд░реАрдм рд╕реЗ рдирдЬрд╝рд░ рдбрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░реЛрддреНрд╕рд╛рд╣рд┐рдд рдХрд░реЗрдЧрд╛: рднрд▓реЗ рд╣реА рдЖрдк рдЗрд╕ рднрд╛рд╖рд╛ рдХреЛ рдЕрдкрдиреЗ рдХрд╛рдо рдореЗрдВ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдореЗрдВ рд╡рд┐рдлрд▓ рд╣реЛрдВ, рдЖрдк рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдХреБрдЫ рдирдпрд╛ рд╕реАрдЦреЗрдВрдЧреЗред
рдХреЛрдб, рдЬреИрд╕рд╛ рдХрд┐ рдЕрдкреЗрдХреНрд╖рд┐рдд рдерд╛,
рдЧрд┐рдЯрд╣рдм рдкрд░ рдкреЛрд╕реНрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛
рд╣реИ , рдФрд░ рдпрд╣ рд╡рд┐рдзрд╛рдирд╕рднрд╛ рдореЗрдВ рдХреЗрд╡рд▓ рдЖрдпрд╛рдд-рдПрд╕ рдФрд░ рдПрд╕рдмреАрдЯреА-рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рд╕реЗ рд▓реЗрдЦ рдореЗрдВ рджрд┐рдП рдЧрдП рд╕реЗ рдЕрд▓рдЧ рд╣реИред
рдореИрдВ рд▓рдЧрднрдЧ рднреВрд▓ рдЧрдпрд╛ рдерд╛ - рд▓реЗрдЦ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдореИрдВрдиреЗ рд╡рд╛рджрд╛ рдХрд┐рдпрд╛ рдерд╛ рдХрд┐ рд╡реЗрдм рд╕реЗрд╡рд╛ рдореЗрдВ рднрд┐рдХреНрд╖реБ рдФрд░ рдЕрдиреНрдп рдмреБрд░реА рдЖрддреНрдорд╛рдПрдВ рд╣реЛрдВрдЧреАред рддреЛ,
flatMap
(рдЙрд░реНрдл
тИЧ
) рдПрдХ рдореЛрдирдбрд┐рдХ рдмрд╛рдЗрдВрдб рд╣реИ, рдФрд░
^
рдСрдкрд░реЗрдЯрд░ рд╕реАрдзреЗ
flatMap
рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИред
рдФрд░ рдЕрдВрдд рдореЗрдВ, рдпрджрд┐ рдЖрдк рдЦрд╛рд░реНрдХреЛрд╡ рдпрд╛ рд╕реИрд░рд╛рдЯреЛрд╡ рдореЗрдВ рд╣реИрдВ рдФрд░ рд╕реНрдХрд╛рд▓рд╛ рдФрд░ рдЕрдХреНрдХрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рджрд┐рд▓рдЪрд╕реНрдк рдЪреАрдЬреЗрдВ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рд▓рд┐рдЦреЗрдВ - рд╣рдо рд╕рдХреНрд╖рдо рд╡рд┐рд╢реЗрд╖рдЬреНрдЮреЛрдВ рдХреА рддрд▓рд╛рд╢ рдХрд░ рд░рд╣реЗ рд╣реИрдВред