Skip to content

Commit 6ed1018

Browse files
authored
feat: custom request (#645)
1 parent 4dc225e commit 6ed1018

File tree

6 files changed

+294
-5
lines changed

6 files changed

+294
-5
lines changed

src/main/scala/algolia/AlgoliaDsl.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ trait AlgoliaDsl
7171
with RestoreDsl
7272
with DictionaryDsl
7373
with ReplaceDsl
74+
with CustomDsl
7475

7576
object AlgoliaDsl extends AlgoliaDsl {
7677

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* The MIT License (MIT)
3+
*
4+
* Copyright (c) 2016 Algolia
5+
* http://www.algolia.com/
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in
15+
* all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
* THE SOFTWARE.
24+
*/
25+
26+
package algolia.definitions
27+
28+
import algolia.http.HttpPayload
29+
import algolia.objects.{CustomRequest, RequestEndpoint, RequestOptions}
30+
import org.json4s.Formats
31+
32+
case class CustomRequestDefinition(
33+
customRequest: CustomRequest
34+
)(implicit val formats: Formats)
35+
extends Definition {
36+
37+
type T = CustomRequestDefinition
38+
39+
override def options(
40+
requestOptions: RequestOptions
41+
): CustomRequestDefinition =
42+
this
43+
44+
override private[algolia] def build(): HttpPayload = {
45+
import customRequest._
46+
HttpPayload(
47+
verb = verb,
48+
path = path,
49+
queryParameters = queryParameters,
50+
body = body,
51+
isSearch = RequestEndpoint.Search == endpoint,
52+
isAnalytics = RequestEndpoint.Analytics == endpoint,
53+
isInsights = RequestEndpoint.Insights == endpoint,
54+
isPersonalization = RequestEndpoint.Personalization == endpoint,
55+
requestOptions = None
56+
)
57+
}
58+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* The MIT License (MIT)
3+
*
4+
* Copyright (c) 2016 Algolia
5+
* http://www.algolia.com/
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in
15+
* all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
* THE SOFTWARE.
24+
*/
25+
26+
package algolia.dsl
27+
28+
import algolia.definitions.CustomRequestDefinition
29+
import algolia.objects.CustomRequest
30+
import algolia.{AlgoliaClient, Executable}
31+
import org.json4s.{Formats, JObject}
32+
33+
import scala.concurrent.{ExecutionContext, Future}
34+
35+
trait CustomDsl {
36+
37+
implicit val formats: Formats
38+
39+
case object custom {
40+
41+
def request(request: CustomRequest): CustomRequestDefinition =
42+
CustomRequestDefinition(request)
43+
}
44+
45+
implicit object CustomRequestDefinitionExecutable
46+
extends Executable[CustomRequestDefinition, JObject] {
47+
override def apply(client: AlgoliaClient, query: CustomRequestDefinition)(
48+
implicit executor: ExecutionContext
49+
): Future[JObject] = { client.request[JObject](query.build()) }
50+
}
51+
}

src/main/scala/algolia/http/HttpPayload.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,21 +31,21 @@ import org.asynchttpclient.{Request, RequestBuilder}
3131

3232
import java.net.InetAddress
3333

34-
private[algolia] sealed trait HttpVerb
34+
sealed trait HttpVerb
3535

36-
private[algolia] case object GET extends HttpVerb {
36+
case object GET extends HttpVerb {
3737
override def toString: String = "GET"
3838
}
3939

40-
private[algolia] case object POST extends HttpVerb {
40+
case object POST extends HttpVerb {
4141
override def toString: String = "POST"
4242
}
4343

44-
private[algolia] case object PUT extends HttpVerb {
44+
case object PUT extends HttpVerb {
4545
override def toString: String = "PUT"
4646
}
4747

48-
private[algolia] case object DELETE extends HttpVerb {
48+
case object DELETE extends HttpVerb {
4949
override def toString: String = "DELETE"
5050
}
5151

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* The MIT License (MIT)
3+
*
4+
* Copyright (c) 2016 Algolia
5+
* http://www.algolia.com/
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in
15+
* all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
* THE SOFTWARE.
24+
*/
25+
26+
package algolia.objects
27+
28+
import algolia.http.HttpVerb
29+
30+
case class CustomRequest(
31+
verb: HttpVerb,
32+
path: Seq[String],
33+
endpoint: RequestEndpoint,
34+
queryParameters: Option[Map[String, String]] = None,
35+
body: Option[String] = None,
36+
requestOptions: Option[RequestOptions] = None
37+
)
38+
39+
sealed trait RequestEndpoint
40+
41+
object RequestEndpoint {
42+
object Search extends RequestEndpoint
43+
object Indexing extends RequestEndpoint
44+
object Analytics extends RequestEndpoint
45+
object Insights extends RequestEndpoint
46+
object Personalization extends RequestEndpoint
47+
}
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
/*
2+
* The MIT License (MIT)
3+
*
4+
* Copyright (c) 2016 Algolia
5+
* http://www.algolia.com/
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in
15+
* all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
* THE SOFTWARE.
24+
*/
25+
26+
package algolia.dsl
27+
28+
import algolia.AlgoliaDsl.custom
29+
import algolia.AlgoliaTest
30+
import algolia.http.{HttpPayload, POST}
31+
import algolia.objects.{CustomRequest, RequestEndpoint}
32+
33+
class CustomRequestTest extends AlgoliaTest {
34+
describe("customRequest") {
35+
it("custom request ") {
36+
custom request CustomRequest(
37+
verb = POST,
38+
path = Seq("1", "indexes", "indexName", "query"),
39+
endpoint = RequestEndpoint.Search,
40+
body = Some("""{"query": "van"}""")
41+
)
42+
}
43+
it("should call search endpoint") {
44+
val json = """{"query":"van","hitsPerPage":1}"""
45+
(custom request CustomRequest(
46+
verb = POST,
47+
path = Seq("1", "indexes", "indexName", "query"),
48+
endpoint = RequestEndpoint.Search,
49+
body = Some(json)
50+
)).build() should be(
51+
HttpPayload(
52+
POST,
53+
Seq("1", "indexes", "indexName", "query"),
54+
body = Some(json),
55+
isSearch = true,
56+
requestOptions = None
57+
)
58+
)
59+
}
60+
61+
it("should call indexing endpoint") {
62+
(custom request CustomRequest(
63+
verb = POST,
64+
path = Seq("1", "indexes", "indexName", "clear"),
65+
endpoint = RequestEndpoint.Indexing
66+
)).build() should be(
67+
HttpPayload(
68+
POST,
69+
Seq("1", "indexes", "indexName", "clear"),
70+
isSearch = false,
71+
requestOptions = None
72+
)
73+
)
74+
}
75+
76+
it("should call analytics endpoint") {
77+
(custom request CustomRequest(
78+
verb = POST,
79+
path = Seq("2", "abtests", "42", "stop"),
80+
endpoint = RequestEndpoint.Analytics
81+
)).build() should be(
82+
HttpPayload(
83+
POST,
84+
Seq("2", "abtests", "42", "stop"),
85+
isSearch = false,
86+
isAnalytics = true,
87+
requestOptions = None
88+
)
89+
)
90+
}
91+
92+
it("should call insights endpoint") {
93+
val json =
94+
"""{"events":[{"eventType":"conversion","eventName":"event-name","index":"index-name","userToken":"user-token","queryID":"query-id","objectIDs":["objectID"]}]}"""
95+
(custom request CustomRequest(
96+
verb = POST,
97+
path = Seq("1", "events"),
98+
endpoint = RequestEndpoint.Insights,
99+
body = Some(json)
100+
)).build() should be(
101+
HttpPayload(
102+
verb = POST,
103+
path = Seq("1", "events"),
104+
body = Some(json),
105+
isSearch = false,
106+
isInsights = true,
107+
requestOptions = None
108+
)
109+
)
110+
}
111+
112+
it("should call personalization endpoint") {
113+
val json =
114+
"""{"eventsScoring":[{"eventName":"buy","eventType":"conversion","score":10}],"facetsScoring":[{"facetName":"brand","score":10}],"personalizationImpact":75}"""
115+
(custom request CustomRequest(
116+
verb = POST,
117+
path = Seq("1", "strategies", "personalization"),
118+
endpoint = RequestEndpoint.Personalization,
119+
body = Some(json)
120+
)).build() should be(
121+
HttpPayload(
122+
verb = POST,
123+
path = Seq("1", "strategies", "personalization"),
124+
body = Some(json),
125+
isSearch = false,
126+
isPersonalization = true,
127+
requestOptions = None
128+
)
129+
)
130+
}
131+
}
132+
}

0 commit comments

Comments
 (0)