Issue #370
Define response model
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 import com.squareup.moshi.Jsondata 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 { posts { edges { node { id name url tagline featuredAt votesCount commentsCount thumbnail { url } } } } }
Here’s how request looks in Insomnia
1 2 3 4 5 6 7 8 9 10 > 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 { "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>
1 2 3 4 5 6 @POST("./" ) suspend fun getTop ( @Body body: Map <String , String> ) : Responseval body = mapOf("query" to queryString)
Troubleshooting Use Network Profiler to inspect failure View > Tool Windows > Profiler
Read more