Issue #370
Define response model
import com.squareup.moshi.Json
data class Response(
@field:Json(name="data") val data: ResponseData
)
data class ResponseData(
@field:Json(name="posts") val posts: Posts
)
data class Posts(
@field:Json(name="edges") val edges: List<Edge>
)
data class Edge(
@field:Json(name="node") val node: Item
)
data class Item(
@field:Json(name="id") val id: String,
@field:Json(name="name") val name: String,
@field:Json(name="url") val url: String,
@field:Json(name="tagline") val tagline: String,
@field:Json(name="featuredAt") val featuredAt: String,
@field:Json(name="votesCount") val votesCount: Int,
@field:Json(name="commentsCount") val commentsCount: Int,
@field:Json(name="thumbnail") val thumbnail: Thumbnail
)
data class Thumbnail(
@field:Json(name="url") val ur: String
)
Here is the query
{
posts {
edges {
node {
id
name
url
tagline
featuredAt
votesCount
commentsCount
thumbnail {
url
}
}
}
}
}
Here’s how request looks in Insomnia
> POST /v2/api/graphql HTTP/1.1
> Host: api.producthunt.com
> User-Agent: insomnia/6.6.2
> Cookie: __cfduid=d9a588136cbb286b156d8e4a873d52a301566795296
> Accept: application/json
> Content-Type: application/json
> Authorization: Bearer 068665d215cccad9123449841463b1248da07123418915a192a1233dedfd23b2
> Content-Length: 241
| {"query":"{\n posts {\n edges {\n node {\n id\n name\n url\n tagline\n featuredAt\n votesCount\n commentsCount\n thumbnail {\n url\n }\n }\n }\n }\n}"}
To post as json, need to use object for Moshi to convert
data class GetTopBody(
@field:Json(name="query") val queryString: String
)
interface Api {
@Headers(
"Content-Type: application/json",
"Accept: application/json",
"Authorization: Bearer 068665d215cccad9123449841463b1248da07123418915a192a1233dedfd23b2",
"Host: api.producthunt.com",
"User-Agent: insomnia/6.6.2"
)
@POST("./")
suspend fun getTop(
@Body body: GetTopBody
): Response
}
And consume it in ViewModel. Use multiline string interpolation. No need to set contentLength
class ViewModel(val repo: Repo): ViewModel() {
val items = liveData {
val queryString = """
{
posts {
edges {
node {
id
name
url
tagline
featuredAt
votesCount
commentsCount
thumbnail {
url
}
}
}
}
}
""".trimIndent()
val body = GetTopBody(queryString)
try {
val response = repo.api().getTop(body)
val items = response.data.posts.edges.map { it.node }
emit(items.toCollection(ArrayList()))
} catch (e: Exception) {
emit(arrayListOf<Item>())
}
}
}
The response looks like
{
"data": {
"posts": {
"edges": [
{
"node": {
"id": "158359",
"name": "Toast",
"url": "https://www.producthunt.com/posts/toast-2?utm_campaign=producthunt-api&utm_medium=api-v2&utm_source=Application%3A+PH+API+Explorer+%28ID%3A+9162%29",
"tagline": "Organise tabs into organised sessions",
"featuredAt": "2019-08-25T07:00:00Z",
"votesCount": 318,
"commentsCount": 16,
"thumbnail": {
"url": "https://ph-files.imgix.net/a169654a-850d-4b1c-80ba-be289f973fb7?auto=format&fit=crop"
}
}
},
{
"node": {
"id": "165621",
"name": "Tree",
"url": "https://www.producthunt.com/posts/tree-2?utm_campaign=producthunt-api&utm_medium=api-v2&utm_source=Application%3A+PH+API+Explorer+%28ID%3A+9162%29",
"tagline": "Write documents in tree-like organisation with Markdown",
"featuredAt": "2019-08-25T09:10:53Z",
"votesCount": 227,
"commentsCount": 11,
"thumbnail": {
"url": "https://ph-files.imgix.net/68b1f007-e630-4c79-8a27-756ec364343f?auto=format&fit=crop"
}
}
}
]
}
}
}
Map
Instead of using an object, we can use Map
. If using HashMap, I get
Unable to create @Body converter for java.util.HashMap<java.lang.String, java.lang.String>
@POST("./")
suspend fun getTop(
@Body body: Map<String, String>
): Response
val body = mapOf("query" to queryString)
Troubleshooting
Use Network Profiler to inspect failure View > Tool Windows > Profiler
Read more
- Product Hunt API Docs https://api.producthunt.com/v2/docs
- API Explorer https://ph-graph-api-explorer.herokuapp.com/
- Posts http://api-v2-docs.producthunt.com.s3-website-us-east-1.amazonaws.com/object/post/
- https://stackoverflow.com/questions/21398598/how-to-post-raw-whole-json-in-the-body-of-a-retrofit-request