Retrofit2 GET request with Id - android

I am trying to make a request in my android project. The url is this one
"https://api.spoonacular.com/recipes/716429/information?includeNutrition=false"
I am using retrofit 2 but i can't figure out how to make it work.
Here is what i tried to do.
I get the id of a recipe and call this function passing the id.
fun applyQueryById(recipeId: Int): String{
val searchByIdQuery = "${recipeId}/information?includeNutrition=false&apiKey=${API_KEY}"
return searchByIdQuery
}
And the GET request is this one
#GET("/recipes/")
suspend fun getRecipeById(
#Query("id") searchById:String
):Response<PersonalizedRecipeResult>
I thinks that because the id is in the middle, making a raw string like i am doing is not a good idea. if anyone could suggest something different I'll appreciate

You are using #Query("id") which will ad the value as query.
From your example, I can see that you want to use #Path
You can use it like this
#GET("/recipes/{id}")
suspend fun getRecipeById(
#Path("id") searchById:String
):Response<PersonalizedRecipeResult>
by this way the searchById will be replaced with {id} in your example call

Related

How to query multiple params like array in retrofit?

I'm trying to translate the next endpoint to an api service endpoint of retrofit, but I didn't found how I need to write the sentence.
The endpoint:
https://balldontlie.io/api/v1/stats?season[]=2018&player_ids[]=237
My try:
#GET("stats/{season}{player_ids")
suspend fun getStatsByPlayerId(#Path("player_ids") playerId: String, #Path("season") season: String): Response<DataNetworkModel>
And advice to fix this? Thank you
For example:
#GET("stats")
suspend fun getStats(
#Query("seasons[]") seasons: List<Int>
): Response<DataNetworkModel>
Calling it this way:
service.getStats(listOf(2015, 2016))
will give you such URL:
https://www.balldontlie.io/api/v1/stats?seasons[]=2015&seasons[]=2016

How to use #Query in Retrofit? Android Kotlin

I'm currently trying to make an ApiInterface. I'm trying to manipulate API URL by using query. So far the URL I'm using is
https://api.themoviedb.org/3/search/movie?api_key={apiKey}&language=en-US&query={query}
The url above I'm trying to change the "query" So I created this interface:
#GET("3/search/movie?api_key=${BuildConfig.MOVIE_TOKEN}&language=en-US&")
fun getMovies(
#Query("query") query: String
): Call<SearchMovieResponse>
And it works well, but what if the case of the URL is this:
https://api.themoviedb.org/3/movie/{id}?api_key=7fad718afb38c7fe3fbe9da94e0d54e6
Where I'm trying to manipulate the {id}. Is the interface like this?
#GET("3/movie/{id}?api_key=${BuildConfig.MOVIE_TOKEN}")
fun getMovieById(
#Query("id") id: String
):Call<SearchDetailMovieResponse>
Please help me understand how to utilize the annotations to modify the API urls
To use the #Query properly in the case of the following URL:
https://api.themoviedb.org/3/movie/{id}?api_key=7fad718afb38c7fe3fbe9da94e0d54e6
You would need to write your interface as such
#GET("3/movie/{id}")
fun getMovieById(
#Path("id") id: String,
#Query("api_key") apiKey: String = BuildConfig.MOVIE_TOKEN
):Call<SearchDetailMovieResponse>
For more information refer to the documentation.
You can use #Path annotation for this.
#GET("3/movie/{id}?api_key=${BuildConfig.MOVIE_TOKEN}")
fun getMovieById(
#Path("id") id: String
):Call<SearchDetailMovieResponse>
Additional Info:
If you have parameter in middle of url and want to give dynamic value then use #Path annotation as you have id in middle of url.
e-g https://test-api/3/profile. 3 is param in middle of url in that case we use #Path
If you don't have parameter in middle of url and want to pass parameters at end of url with key value pair then better to use #Query
e-g https://test-api/profile?user_id=3 user_id is key value parameter in that case we use #Query.
Note: I am sharing as far as I understood.

What is Call<> in retrofit?

I am learning retrofit and cannot understand what is Call<> in that means.
Even the docs are too hard to understand.
Can someone give a clear explanation on this?
Think of Call as a simple class which wraps your API response and you need this class make an API call and provide listeners/callback to notify you with error and response , although if you use kotlin coroutines then after version 2.6.0 or retrofit you can totally abandon Call , you can directly return response from the function and you don't need any callback which is very clean.
do if like
#GET("users/{id}")
suspend fun user(#Path("id") id: Long): User
or
#GET("users/{id}")
suspend fun user(#Path("id") id: Long): Response<User>
Call is a method to request to the webserver/API to get data.(Based on my understanding)

Identical Retrofit call throws Unable to create call adapter error while the other one works

I am trying to setup Paging 3 with Retrofit and I am unable to get past this call.
val response = redditAPI.getSubreddits(mBearer, mWhere, position, params.loadSize)
The getSubreddits method is this
#GET("/subreddits/mine/{where}")
fun getSubreddits(
#Header("Authorization") bearer: String,
#Path("where") where: String,
#Query("after") after: String,
#Query("count") count: Int
): SubredditResponse
I have checked with a debugger and the inputs are exactly what I want.
A friend implemented this
#GET("{subreddit}/{filter}")
suspend fun getPostList(
#Path("subreddit") subreddit: String,
#Path("filter") filter: String,
#Query("after") after: String,
#Query("count") count: Int,
#Header("Authorization") bearer: String
): Listing
and he used this call
val response = redditAPI.getPostList(mSubreddit, mFilter, position, params.loadSize, mBearer)
and it works perfectly. I read that this error is related to the fact that Call should be used as a return type but that is the way Paging 3 is set up with Retrofit and I can see no reason why it won't work. It's probably something stupid but I really cannot see what it is. The inputs from the other levels above this call are also correct, also checked with a debugger and all seem well.
Thank you in advance.
So, the problem was the missing suspend keyword before declaring the function. The Retrofit error was not helpful at all and I have little experience with Kotlin, so I had no idea the suspend keyword was that important. Lesson learned.

How to resolve "#Url cannot be used with #PUT URL (parameter #1)"

I want to use #PUT and #Url together, but it throws an IllegalArgumentException
Edit
#PUT
fun editPost(
#Url() url: String = "xxxx/threads/{tid}",
#Path("tid") postId:Long,
#Body x: X
)
This answer is based on the assumption of you using Retrofit Library to make a API call. If that's not the case, my apologies and let me know so I can modify/remove the answer.
From what I've researched, you've probably implemented your interface method like the following:
#PUT("")
Call...
With this call, you should encounter java.lang.IllegalArgumentException: Missing either #GET URL or #Url parameteras you've not provided the addition parameter which is needed to complete the API call.
Therefore, you must keep the base URL in the mainActivity where you'll be making the call and route of the API within the bracket of the interface
#PUT("user/id")
or if you want to keep it blank as original, you must use #PUT(".") as this will declare that your final URL is the same as the Base URL provided in the mainActivity.
You were very close...
#PUT("xxxx/threads/{tid}"
fun editPost(
#Path("tid") postId: Long,
#Body x: X
)

Categories

Resources