Skip to content

Commit 3d570ba

Browse files
authored
Merge pull request #12 from xebia-functional/11-create-get-details
Create get details
2 parents dcba6a2 + 1301494 commit 3d570ba

File tree

12 files changed

+247
-11
lines changed

12 files changed

+247
-11
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ If the server starts successfully, you'll see the following output:
2020

2121
```
2222
2024-12-04 14:32:45.584 [main] INFO Application - Application started in 0.303 seconds.
23-
2024-12-04 14:32:45.682 [main] INFO Application - Responding at http://0.0.0.0:8081
23+
2024-12-04 14:32:45.682 [main] INFO Application - Responding at http://127.0.0.1:8081
2424
```
2525

2626
## Endpoints

src/main/kotlin/controller/BGGController.kt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,16 @@ fun Route.bgg(application: Application) {
2121
}
2222

2323
get("/details") {
24-
call.respondText(bggService.getGameDetails("1"))
24+
val id = call.request.queryParameters["id"] ?: throw BadRequestException("Id can not be empty")
25+
26+
if (id.isBlank()) {
27+
throw BadRequestException("Id can not be empty")
28+
}
29+
30+
if (id.toIntOrNull() == null || id.toIntOrNull()!! <= 0) {
31+
throw BadRequestException("Id must be a number positive")
32+
}
33+
34+
call.respond(bggService.getGameDetails(id))
2535
}
2636
}

src/main/kotlin/model/BGGGameItemYearPublished.kt renamed to src/main/kotlin/model/BGGPropertyValue.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package com.es.model
33
import com.fasterxml.jackson.annotation.JsonProperty
44
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty
55

6-
data class BGGGameItemYearPublished(
6+
data class BGGPropertyValue(
77
@JacksonXmlProperty(isAttribute = true)
88
@JsonProperty("value")
99
val value: String? = null
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.es.model
2+
3+
import com.es.model.detail.BGGGameDetailItem
4+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
5+
import com.fasterxml.jackson.annotation.JsonProperty
6+
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper
7+
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty
8+
9+
@JsonIgnoreProperties(ignoreUnknown = true)
10+
data class DetailResponse(
11+
@JacksonXmlElementWrapper(useWrapping = false)
12+
@JacksonXmlProperty(localName = "item")
13+
@JsonProperty("items")
14+
val items: List<BGGGameDetailItem>? = emptyList(),
15+
)

src/main/kotlin/model/SearchResponse.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.es.model
22

3+
import com.es.model.search.BGGGameItem
34
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
45
import com.fasterxml.jackson.annotation.JsonProperty
56
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper
@@ -10,5 +11,5 @@ data class SearchResponse(
1011
@JacksonXmlElementWrapper(useWrapping = false)
1112
@JacksonXmlProperty(localName = "item")
1213
@JsonProperty("items")
13-
val items: List<BGGGameItem> = emptyList(),
14+
val items: List<BGGGameItem>? = emptyList(),
1415
)
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package com.es.model.detail
2+
3+
import com.es.model.search.BGGGameItemName
4+
import com.es.model.BGGPropertyValue
5+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
6+
import com.fasterxml.jackson.annotation.JsonProperty
7+
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper
8+
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty
9+
10+
@JsonIgnoreProperties(ignoreUnknown = true)
11+
data class BGGGameDetailItem(
12+
@JacksonXmlProperty(isAttribute = true)
13+
@JsonProperty("id")
14+
val id: String,
15+
16+
@JacksonXmlProperty(isAttribute = true)
17+
@JsonProperty("type")
18+
val type: String,
19+
20+
@JacksonXmlProperty(localName = "thumbnail")
21+
@JsonProperty("thumbnail")
22+
val thumbnail: String? = null,
23+
24+
@JacksonXmlProperty(localName = "image")
25+
@JsonProperty("image")
26+
val image: String? = null,
27+
28+
@JacksonXmlElementWrapper(useWrapping = false)
29+
@JacksonXmlProperty(localName = "name")
30+
@JsonProperty("names")
31+
val names: List<BGGGameItemName>? = null,
32+
33+
@JacksonXmlProperty(localName = "description")
34+
@JsonProperty("description")
35+
val description: String? = null,
36+
37+
@JacksonXmlElementWrapper(useWrapping = false)
38+
@JacksonXmlProperty(localName = "yearpublished")
39+
@JsonProperty("yearpublished")
40+
val yearPublished: BGGPropertyValue? = null,
41+
42+
@JacksonXmlElementWrapper(useWrapping = false)
43+
@JacksonXmlProperty(localName = "minplayers")
44+
@JsonProperty("minplayers")
45+
val minPlayers: BGGPropertyValue? = null,
46+
47+
@JacksonXmlElementWrapper(useWrapping = false)
48+
@JacksonXmlProperty(localName = "maxplayers")
49+
@JsonProperty("maxplayers")
50+
val maxPlayers: BGGPropertyValue? = null,
51+
52+
@JacksonXmlElementWrapper(useWrapping = false)
53+
@JacksonXmlProperty(localName = "playingtime")
54+
@JsonProperty("playingtime")
55+
val playingTime: BGGPropertyValue? = null,
56+
57+
@JacksonXmlElementWrapper(useWrapping = false)
58+
@JacksonXmlProperty(localName = "minplaytime")
59+
@JsonProperty("minplaytime")
60+
val minPlayTime: BGGPropertyValue? = null,
61+
62+
@JacksonXmlElementWrapper(useWrapping = false)
63+
@JacksonXmlProperty(localName = "maxplaytime")
64+
@JsonProperty("maxplaytime")
65+
val maxPlayTime: BGGPropertyValue? = null,
66+
67+
@JacksonXmlElementWrapper(useWrapping = false)
68+
@JacksonXmlProperty(localName = "minage")
69+
@JsonProperty("minage")
70+
val minAge: BGGPropertyValue? = null,
71+
72+
@JacksonXmlElementWrapper(useWrapping = false)
73+
@JacksonXmlProperty(localName = "link")
74+
@JsonProperty("links")
75+
val links: List<BGGGameDetailLink>? = null,
76+
)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.es.model.detail
2+
3+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
4+
import com.fasterxml.jackson.annotation.JsonProperty
5+
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty
6+
7+
@JsonIgnoreProperties(ignoreUnknown = true)
8+
data class BGGGameDetailLink(
9+
@JacksonXmlProperty(isAttribute = true)
10+
@JsonProperty("type")
11+
val type: String? = null,
12+
13+
@JacksonXmlProperty(isAttribute = true)
14+
@JsonProperty("id")
15+
val id: String? = null,
16+
17+
@JacksonXmlProperty(isAttribute = true)
18+
@JsonProperty("value")
19+
val value: String? = null
20+
)

src/main/kotlin/model/BGGGameItem.kt renamed to src/main/kotlin/model/search/BGGGameItem.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
package com.es.model
1+
package com.es.model.search
22

3+
import com.es.model.BGGPropertyValue
34
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
45
import com.fasterxml.jackson.annotation.JsonProperty
56
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty
@@ -19,5 +20,5 @@ data class BGGGameItem(
1920
@JacksonXmlElementWrapper(useWrapping = false)
2021
@JacksonXmlProperty(localName = "yearpublished")
2122
@JsonProperty("yearpublished")
22-
val yearPublished: BGGGameItemYearPublished? = null
23+
val yearPublished: BGGPropertyValue? = null
2324
)

src/main/kotlin/model/BGGGameItemName.kt renamed to src/main/kotlin/model/search/BGGGameItemName.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
package com.es.model
1+
package com.es.model.search
22

3+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
34
import com.fasterxml.jackson.annotation.JsonProperty
45
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty
56

7+
@JsonIgnoreProperties(ignoreUnknown = true)
68
data class BGGGameItemName(
79
@JacksonXmlProperty(isAttribute = true)
810
@JsonProperty("type")

src/main/kotlin/service/BGGService.kt

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.es.service
22

3+
import com.es.model.DetailResponse
34
import com.es.model.SearchResponse
45
import com.fasterxml.jackson.dataformat.xml.XmlMapper
56
import io.ktor.client.*
@@ -15,8 +16,7 @@ class BGGService(private val config: ApplicationConfig) {
1516
}
1617

1718
private val xmlMapper = XmlMapper()
18-
private val baseUrl = config.propertyOrNull("ktor.externalApi.bggUrl")?.getString()
19-
19+
private val baseUrl = config.propertyOrNull("ktor.externalApi.bggUrl")?.getString() ?: "https://boardgamegeek.com/xmlapi2/"
2020
suspend fun searchGames(query: String, exact: Int?): SearchResponse {
2121
try {
2222
val url = buildString {
@@ -37,7 +37,21 @@ class BGGService(private val config: ApplicationConfig) {
3737
}
3838
}
3939

40-
suspend fun getGameDetails(id: String): String {
41-
return "details"
40+
suspend fun getGameDetails(id: String): DetailResponse {
41+
try {
42+
val url = buildString {
43+
append(baseUrl)
44+
append("thing?")
45+
append("id=${id}")
46+
}
47+
48+
val response: HttpResponse = client.get(url)
49+
50+
val responseBody = response.bodyAsText()
51+
52+
return xmlMapper.readValue(responseBody, DetailResponse::class.java)
53+
} catch (e: Exception) {
54+
throw RuntimeException("Error in BoardGameGeek API: $e")
55+
}
4256
}
4357
}

0 commit comments

Comments
 (0)