GET URL with constant and dynamic params, with Retrofit2 - android

I have a GET URL like that:
http://myrestapi.com/?method=search&name=nametosearch&format=json
I've written my service like that:
#GET("?method=search")
Observable<List<Album>> getAlbums(#Query("name") String searchedName);
Unfortunately, I don't know how to add &format=json at the end.
I've tried:
#GET("?method=search&name={searched_name}&format=json")
Observable<List<Album>> getAlbums(#Path("searched_name") String searchedName);
But it doesn't work since searched_name is not a Path element.
Can you please help me with that?

If you append &format=json after ?method=search and use #Query("name") then name will be appended after the format parameter. If the server is handling the parameters correctly the order shouldn't matter.
i.e.
#GET("?method=search&format=json")
Single<List<Album>> getAlbums(#Query("name") String name);
Would translate to: http://myrestapi.com/?method=search&format=json&name=name

Related

Why we add Query parameters in Get request?

I am very much new to android and I was studying the Retrofit 2 for networking, to send the Get why we are use the Query parameter?
It is not necessary to send Query Parameters with GET requests. It is something related to how the end point is configured on the API you are trying to consume.
While designing APIs especially GET methods certain parameters can be kept optional by specifying them as query parameters.
#GET("location")
Response getUser(#QueryParam("name") String name);
can be called by both
/location
/location?name=test
Query Parameter is not merely confined to GET requests. It can be used with other methods too e.g., DELETE, etc.
This is a concept related to HTTP methods
Retrofit uses annotations to translate defined keys and values into appropriate format. Using the #Query("key") String value annotation will add a query parameter with name key and the respective string value to the request url (of course you can use other types than string :)).
Actually, there are APIs with endpoints allowing you to pass (optionally) multiple query parameters. You want to avoid a service method declaration like the one below with “endless” options for request parameters:
public interface NewsService() {
#GET("/news")
Call<List<News>> getNews(
#Query("page") int page,
#Query("order") String order,
#Query("author") String author,
#Query("published_at") Date date,
…
);
}
You could call the .getNews service method with null values for each of the parameters to make them optional. Retrofit will ignore null values and don’t map them as query parameters. However, there is a better solution to work with complex API endpoints having various options for query parameters. Don’t worry, Retrofit got you covered!
You can explore more from the given link below:-
https://futurestud.io/tutorials/retrofit-2-add-multiple-query-parameter-with-querymap
Lets say you have following api to call:
https://api.themoviedb.org/3/movie/now_playing/api_key=1
So for you to pass the value for "api_key" dynamically, you should use #Query("api_key") as:
#GET("movie/now_playing")
Call<MovieData> getMovieData(#Query("api_key") String apiKey);
So here is a simple way to understand it for those that might want to use Retrofit query. Please check as follows ....
If you specify #GET("Search?one=5"), then any #Query("two") must be appended using &, producing something like Search?one=5&two=7.
If you specify #GET("Search"), then the first #Query must be appended using ?, producing something like Search?two=7.
That's how Retrofit works.
When you specify #GET("Search?"), Retrofit thinks you already gave some query parameter, and appends more query parameters using &.
Remove the ?, and you will get the desired result.
enter String BASE_URL = "https://api.test.com/";
String API_KEY = "SFSDF24242353434";
#GET("Search") //i.e https://api.test.com/Search?
Call<Products> getProducts(
#Query("one") String one,
#Query("two") String two,
#Query("key") String key
)
Result:
https://api.test.com/Search?one=Whatever&two=here&key=SFSDF24242353434

Why do Glide only work on raw string url data? (Android Studio)

I can successfully use a string url with glide to get the image I want:
glideVariable!!.loadImageUrl("https://firebasestorage.googleapis.com/v0/b/healthandchocolate-46f3d.appspot.com/o/cookies%2FcookiesImg1.jpg?alt=media&token=63721d7d-207e-441c-9387-14dced13d3c8")
but when I try to use the very same url, stored in a variable, the image doesn't load:
glideVariable!!.loadImageUrl(recipeArray[1].recipeImage.toString())
I have done a Log.d on recipeArray[1].recipeImage.toString() and it does indeed contain the very same url that worked on my first example, using raw string data.
I have used escape commands to encapsulate the variable in quotation marks like this:
glideVariable!!.loadImageUrl("${recipeArray[1].recipeImage.toString()}")
but it still doesn't work. I have also tried to cast it as URL and URI, but still nothing. Any ideas? Can glide only use raw string data?
UPDATE
I noted that recipeArray[1].recipeImage contain both a key and a value. Perhaps this is the problem. It doesn't access the url string directly. How do I make sure just to use the string value? It looks like this:
DataSnapshot { key = recipeImageFirebase, value = https://firebasestorage.googleapis.com/v0/b/healthandchocolate-46f3d.appspot.com/o/cookies%2FcookiesImg1.jpg?alt=media&token=63721d7d-207e-441c-9387-14dced13d3c8 }
OK, got it now. The recipeArray[1].recipeImage.toString() was a data snapshot containing both a key and a string. I went back to when I stored the variable:
val image = item.child("recipeImageFirebase")
tempRecipe.recipeImage = image.toString()
and changed the last part to
tempRecipe.recipeImage = image.value.toString()
Now it only contains the string value and not the key "recipeImageFirebase" as well!

Retrofit2 no key name on URL parameter

I'm using Retrofit2
I need to ask api with simply get looking like that
http://1.1.1.1/get?key=value1&value2
How can I have query with only value? As value2 in above example?
I've tried like here:
Retrofit no key name on URL parameter
Retrofit change ? sign to %3F.
#Query("") will do something like this &=value2
#QueryMap("") with empty value will od something like this &value2=
Any ideas?
In this kind of case you can directly call entire URL.
#GET()
Call<ResponseVO> test(#Url() String url);
And call
test("http://1.1.1.1/get?key=value1&value2")
With the latest version of Retrofit2 #QueryName
#GET("http://1.1.1.1/get")
Call<Object> getYourData(#Query("key") String key, #QueryName String value);
When you call the method, each query name is appended to the URL. You can see the JavaDoc here: https://square.github.io/retrofit/2.x/retrofit/retrofit2/http/QueryName.html
Please encode query parameter value value1&value2 to value1%26value2 like
http://1.1.1.1/get?key=value1&value2
to
http://1.1.1.1/get?key=value1%26value2
when you passing in
#GET("http://1.1.1.1/get?")
Call<Object> getYourData(#Query("key") String value);
#GET("http://1.1.1.1/get?key=value")
Call<Object> getYourData(#Query("value") String value);
And then when you call "getYourData" just put your value1 and value2 in separate strings and concatenate them and pass that new string to "getYourData" method.
P.S dont forget this sign "&" when merging two strings together.

Replace string in Retrofit GET request in Android

I am trying to replace String in my GET url. Query looks as follow:
#GET("read/something/Books?$filter=(substringof('{filter}',Description)+or+substringof('{filter}',Code)+or+substringof('{filter}',Title)+or+substringof('{filter}',Barcode))")
Call<ApiResponse<Book>> getFilteredBooks(#Path("filter") String filter);
So I want to replace {filter} with dynamic string.
I get an error:
java.lang.IllegalArgumentException: URL query string "$filter=(substringof('{filter}',Description)+or+substringof('{filter}',Code)+or+substringof('{filter}',Title)+or+substringof('{filter}',Barcode))" must not have replace block. For dynamic query parameters use #Query.
I couldn't find any other suitable annotation that would work as expected.
You should use query parameters, like:
#GET("read/something/Books")
Call<ApiResponse<Book>> getFilteredBooks(#Query("$filter") String filter);
This will create url like .../read/something/Books?$filter={parameter you sent}.

Only get part of string in android?

Okay I wasn't really sure how to word this question, but basically what I want to do is, I got a url from a webView in android, and I need to put part of that url into a string, the url will look something like this: http://localhost/?code=4/3pakksajdfASDFwek.4nsKfAYN7XQVshQV0ieZDAp-PrgEcAI and I only want the part after code=, is that possible? Thanks
int start = my_string.indexOf("=");
String suffix = my_string.substring(start + 1);
If other parameters can be on the URL, or code is not always first parameter:
String url = "http://localhost/?code=4/3pakksajdfASDFwek.4nsKfAYN7XQVshQV0ieZDAp-PrgEcAI";
String code = url.replaceAll(".*(?:[?]|[&])code=([^&]+)","\1");
tests here: http://fiddle.re/nxfv
If you are totally sure the URL never has other form, you can use indexOf and substring.
Otherwise, it is better if you use URI class to extract out the query part of the URL (use getRawQuery just to be safe), then tokenize it with split along & character and find the correct key-value pair to obtain the correct value. This method is not as brittle as indexOf method above.

Categories

Resources