Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace common path parameters in retrofit 2 with okhttp

I have some service urls with the same baseUrl. For some urls there will be some common used parameters, for example an apiVersion or locale. But they don't have to be in every url, so I can't add them to the baseUrl.

.../api/{apiVersion}/{locale}/event/{eventId}
.../api/{apiVersion}/{locale}/venues
.../api/{apiVersion}/configuration

I don't want to add these parameters in the retrofit interface. In retrofit 1, I made an interceptor and used RequestFacade.addPathParam(..., ...) to fill these common path parameters for every url.

For retrofit 2, I can't seem to find a proper way to do this with okhttp. The only way I see this being possible right now is to get the HttpUrl from Chain.request().httpUrl(); in an okhttp Interceptor and manipulate that one myself, but I don't know if this is the best way to go.

Has anyone come across a better way to replace path parameters in an okhttp Interceptor?

At the time of writing I'm using retrofit:2.0.0-beta2 and okhttp:2.7.2.

like image 417
Siebe Avatar asked Jan 11 '16 14:01

Siebe


People also ask

How do I add OkHttp to retrofit?

Solution 1: Sharing Default OkHttp Instance In order to make them share a single OkHttp instance, you can simply pass it explicitly on the builder: OkHttpClient okHttpClient = new OkHttpClient(); Retrofit retrofitApiV1 = new Retrofit. Builder() . baseUrl("https://futurestud.io/v1/") .

Which annotation is used in retrofit to add a parameter to the@ get method?

You're using the @Query annotation for your parameter declaration within the interface methods. This tells Retrofit to translate the provided query parameter name and value to the request and append the fields to the url.

What is query annotation in retrofit?

Retrofit uses annotations to define query parameters for requests. The annotation is defined before method parameters and specifies the request parameter name. The desired value for this parameter is passed during method call.


1 Answers

For retrofit 2, I can't seem to find a proper way to do this with okhttp. The only way I see this being possible right now is to get the HttpUrl from Chain.request().httpUrl(); in an okhttp Interceptor and manipulate that one myself, but I don't know if this is the best way to go.

My implementation using okhttp:3.2

    class PathParamInterceptor implements Interceptor {
        private final String mKey;
        private final String mValue;

        private PathParamInterceptor(String key, String value) {
            mKey = String.format("{%s}", key);
            mValue = value;
        }

        @Override
        public Response intercept(Chain chain) throws IOException {
            Request originalRequest = chain.request();

            HttpUrl.Builder urlBuilder = originalRequest.url().newBuilder();
            List<String> segments = originalRequest.url().pathSegments();

            for (int i = 0; i < segments.size(); i++) {
                if (mKey.equalsIgnoreCase(segments.get(i))) {
                    urlBuilder.setPathSegment(i, mValue);
                }
            }

            Request request = originalRequest.newBuilder()
                    .url(urlBuilder.build())
                    .build();
            return chain.proceed(request);
        }
    }
like image 190
Andriy Petruk Avatar answered Oct 06 '22 01:10

Andriy Petruk