Retrofit creating endpoints using #Path and #Query parameter - android

I had to call api endpoints on this query url /api/AssignedStaffClassSection/?StaffId=3071 I tried this way but failed.
Option 1 using #Query parameter
#GET(WebSchoolApi._SAPI + "/AssignedStaffClassSection/")
Call<StaffAssignedClassSectionModel> getAssignedClassSection(#Query("StaffId") String staffId);
Option 2 using #Path parameter
#GET(WebSchoolApi._SAPI + "/AssignedStaffClassSection/?StaffId={staffId}")
Call<StaffAssignedClassSectionModel> getAssignedClassSection(#Path("staffId") String _staffid);
Is there any mistake that I made over?
Thank your for your help.

For GET request you mast to use:
example.com/api/AssignedStaffClassSection/?StaffId=3071
Correct:
#GET(WebSchoolApi._SAPI + "/AssignedStaffClassSection/")
Call<StaffAssignedClassSectionModel> getAssignedClassSection(#Query("StaffId") String staffId);
You should to use #Path for
example.com/api/AssignedStaffClassSection/3071/StaffId
And it will looks like:
#GET(WebSchoolApi._SAPI + "/AssignedStaffClassSection/{staffId}/StaffId")
Call<StaffAssignedClassSectionModel> getAssignedClassSection(#Path("staffId") String _staffid);
Crash may produce if you use wrong tool.

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

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.

Retrofit 2 error URL query string must not have replace block

I am trying to call a legacy API using Retrofit 2, this is the URL "/api/0.3/v3/?endpoint=/admin/customers/6728382/addresses.json" and this is the interface method
#GET("/api/0.3/v3/?endpoint=/admin/customers/{customerId}/addresses.json")
Single<GetCustomerAddressesResponse> getUserAddresses(#Path("customerId") String customerId);
However I am getting this error,
"URL query string
"endpoint=//admin/customers/{customerId}/addresses.json" must not have
replace block. For dynamic query parameters use #Query."
How can I fix this?
I think id has to be int type. Try to change String to int.
"URL query string "endpoint=//admin/customers/{customerId}/addresses.json" must not have replace block. For dynamic query parameters use #Query."
As it suggests you should use #Query instead of #Path.
Single<GetCustomerAddressesResponse> getUserAddresses(#Query("customerId") String customerId);
You may like to read this in details about #Query annotation https://square.github.io/retrofit/2.x/retrofit/index.html?retrofit2/http/Query.html

How do I use #Path in query string in Retrofit?

I have an URL like http://www.example.com/index.php?apiex/teacher/2 and I want http://www.example.com/index.php?apiex/teacher/{teacher_id}, not like this http://www.example.com/index.php?apiex/teacher?teacher_id=2.
Using like getTeacher(#Path("teacher_id") String teacherId) gives me an exception:
java.lang.IllegalArgumentException: URL query string "apiex/teacher/{teacher_id}" must not have replace block. For dynamic query parameters use #Query.
My Retrofit interface is like this:
#GET("apiex/teacher/{teacher_id}")
Observable<List<Teachers>>getTeacher(#Path("teacher_id") String teacherId);
and the base URL is http://www.example.com/index.php?. And also I cant remove ? from this. I saw this, but I wanted it like above.
make the baseurl like this http://www.example.com/index.php/ instead of
http://www.example.com/index.php? as it sees what after ? as query that's why it says that the block after the ? is query

Arguments to Endpoints method change order

I am using Google App Engine with Cloud Endpoints for a simple Android application. In the backend I have the following API method, deployed to GAE:
#ApiMethod(name = "getGroupInfo", path = "groups")
public GroupInfo getGroupInfo(#Named("session") String sessionString, #Named("groupID") String groupID)
throws ForbiddenException
{
Logger.getAnonymousLogger().warning("Session string is: " + sessionString);
Logger.getAnonymousLogger().warning("GroupID is: " + groupID); }
The problem is that when I call the method from the Android client, arguments are passed in reverse order to the method: the string I pass as the first argument in client is group ID in server backend, and the other way around.
Any help would be appreciated, thank you!
AS you can read here [1]:
Method parameters in the generated client library are in alphabetical order, regardless of the original order in the backend method. As a result, you should be careful when editing your methods, especially if there are several parameters of the same type. The compiler will not be able to catch parameter-ordering errors for you.
[1] https://cloud.google.com/solutions/mobile/google-cloud-endpoints-for-android/

Categories

Resources