Прочитайте и поймите распылительную DSL
Я новичок в спрей. У меня есть работа с несколькими странными (для меня) языками программирования, такими как python, JQuery и т. Д. С ними я, по крайней мере, мог понять, что делает какой-то сегмент кода. К сожалению, с помощью Spray я не могу прочитать и понять даже простой код.
Может кто-нибудь, пожалуйста, помогите мне прочитать (опишите словом, что делает код) следующий простой блок кода.
Примечание: я знаю, что это очень высокий уровень, он выберет параметр url и сложит их вместе. Но я хочу четко понимать этот кристалл кодового блока, как я мог бы научить кого-то другого. HNil, Directive1, Directive1, ::
некоторые, что странно для меня.
val twoIntParameters: Directive[Int :: Int :: HNil] =
parameters('a.as[Int], 'b.as[Int])
val myDirective: Directive1[String] =
twoIntParameters.hmap {
case a :: b :: HNil => (a + b).toString
}
// test `myDirective` using the testkit DSL
Get("/?a=2&b=5") ~> myDirective(x => complete(x)) ~> check {
responseAs[String] === "7"
}
2 ответа
Распылитель строится вокруг концепции Directive
,
Вы можете думать о Directive
как преобразование по HTTP-запросу.
Количество элементов, связанных с директивой - это число аргументов, передаваемых по цепочке преобразования после выполнения преобразования.
Directive0
директива, которая не предоставляет (или не извлекает) никаких аргументов.
Directive1[A]
предоставляет один аргумент типа A
,
Directive[A :: B :: HNil]
предоставляет 2 аргумента типов A
а также B
или - если быть более точным - предоставляет гетерогенный список, состоящий из A
а также B
(реализация бесформенная HList
).
Давайте возьмем примеры в вашем коде
val twoIntParameters: Directive[Int :: Int :: HNil] =
parameters('a.as[Int], 'b.as[Int])
Вы определяете новую директиву, которая извлекает два целых числа из запроса HTTP, т.е. имеет тип Directive[Int :: Int :: HNil]
, Реализация просто использует директиву, предоставленную уже спреем, т.е. parameters
, parameters
директива, которая позволяет извлечь параметры запроса из HTTP-запроса и преобразовать их в определенный тип, в данном случае Int
для обоих параметров.
val myDirective: Directive1[String] =
twoIntParameters.hmap {
case a :: b :: HNil => (a + b).toString
}
myDirective
директива, которая извлекает один параметр типа String
,
В его реализации используются ранее определенные twoIntParameters
директива и отображает ее результат, применяя к ней преобразование. В этом случае мы берем два Int
суммируя их и превращая результат в String
,
Итак, что с hmap
? Это просто способ работы с директивами, которые возвращают бесформенный HList
, hmap
требует функции, которая HList
ни к чему, в этом случае String
,
HList
s может быть сопоставлен с шаблоном, как обычная скала List
и вот что вы видите в примере.
Наконец, это просто представление о том, как директивы работают с функциональной точки зрения. Если вы хотите понять тонкие детали синтаксиса DSL, вам придется немного покопаться и прочитать о шаблоне магнитов.
Здесь я нашел очень хорошую мастерскую.