A type-safe HTTP client for Android and the JVM

Related tags

android java
Overview

Retrofit

A type-safe HTTP client for Android and Java.

For more information please see the website.

Download

Download the latest JAR or grab from Maven central at the coordinates com.squareup.retrofit2:retrofit:2.9.0.

Snapshots of the development version are available in Sonatype's snapshots repository.

Retrofit requires at minimum Java 8+ or Android API 21+.

R8 / ProGuard

If you are using R8 the shrinking and obfuscation rules are included automatically.

ProGuard users must manually add the options from retrofit2.pro. You might also need rules for OkHttp and Okio which are dependencies of this library.

License

Copyright 2013 Square, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Issues
  • Retrofit 2.0 API Spec (Working Draft)

    Retrofit 2.0 API Spec (Working Draft)

    This is a living spec for what will be v2 of Retrofit.

    Goals

    • Broaden the scope of how you can process successful responses and handle the results of various exceptions throughout the stack. Currently there's a mix of exceptions, wrapped types, and callbacks depending on the usage of synchronous or asynchronous API declarations.
    • Unify API declaration so that both synchronous and asynchronous consumption of a resource does not change its declaration.
    • Introduce better request and response interceptors which allow for both tweaks to existing requests or full on replacement (e.g., for signing purposes).
    • Allow simple request retry and cancel support without the need to talk to the RestAdapter or generated interface instance.
    • Completely decouple interface declaration parsing from request invocation and processing and expose the shim layer between the two as a extension-based system for customization. This will be used to (hopefully) facilitate RxJava integration as an extensions rather than being baked into the core of the library itself

    Changes

    Annotation Processors

    An annotation processor will be embedded inside the core artifact for compile-time verification of REST API interface declarations.

    A second annotation processor will be provided as a separate artifact for full code generation of a class implementation of each API interface.

    The RestAdapter will always do a read-through cached lookup for the generated classes since it has no knowledge of whether the code-gen processor was used and we don't want to place the burden on the caller either.

    Request Object

    All interface declarations will be required to return an object through which all interaction will occur. The behavior of this object will be similar to a Future and will be generic typed (T) for the success response type (ref: #231).

    @GET("/foo")
    Call<Foo> getFoo();
    

    Callers can synchronously call .execute() which will return type T. Exceptions will be thrown for any error, network error, unsuccessful response, or unsuccessful deserialization of the response body. While these exceptions will likely extend from the same supertype, it's unclear as to whether that supertype should be checked or unchecked.

    interface Api {
      @GET("/{user}/tweets")
      Call<List<Tweet>> listTweets(@Path("user") String username);
    }
    
    List<Tweet> tweets = api.listTweets("JakeWharton").execute();
    

    Callers can also supply callbacks to this object for asynchronous notification of the response. The traditional Callback<T> of the current version of Retrofit will be available. One change will be that the error object passed to failure will not be the same exception as would be thrown in synchronous execution but rather something a bit more transparent to the underlying cause.

    interface Api {
      @GET("/{user}/tweets")
      Call<List<Tweet>> listTweets(@Path("user") String username);
    }
    
    Call<List<Tweet>> c = api.listTweets("JakeWharton");
    c.execute(new Callback<List<Tweet>>() {
      @Override public void success(List<Tweet> response) { }
      // ...
    }
    

    TODO describe error handling

    public abstract class ResponseCallback<T> {
      public abstract void success(T response);
    
      public void networkError(IOException e) {
        error(ErrorType.NETWORK, -1, e);
      }
      public void processingError(Exception e) {
        error(ErrorType.PROCESSING, -1, e);
      }
      public void httpError(int status, ...) {
        error(ErrorType.HTTP, status, e);
      }
      public void error(ErrorType errorType, int status, Exception e) {
        throw new RuntimeException(.., e);
      }
    
      public enum ErrorType { NETWORK, PROCESSING, HTTP }
    }
    

    The call object is also an obvious place for handling the retry and cancelation of requests. Both are a simple, no-args method on the object which can only be called at appropriate times.

    • cancel() is a no-op after the response has been received. In all other cases the method will set any callbacks to null (thus freeing strong references to the enclosing class if declared anonymously) and render the request object dead. All future interactions with the request object will throw an exception. If the request is waiting in the executor its Future will be cancelled so that it is never invoked.
    • retry() will re-submit the request onto the backing executor without passing through any of the mutating pipeline described above. Retrying a request is only available after a network error or 5XX response. Attempting to retry a request that is currently in flight, after a non-5XX response, after an unexpected error, or after calling cancel() will throw an exception.

    Extension System

    In order to facilitate libraries which offer semantics on both synchronous and asynchronous operations without requiring a wrapper, we will introduce a system which we will tentatively refer to as extensions. An extension instance will be registered with the RestAdapter and associate itself as handling an explicit interface method return type.

    By default, Retrofit will install its own extension which handles the aforementioned Call type for both synchronous and asynchronous request execution.

    The current (albeit experimentally denoted) RxJava integration will also be provided as an opt-in extension. This extension will register itself as handling the Observable type which will allow the declaration of interfaces which return this type.

    interface FooService {
      @GET("/foos")
      Observable<Foo> getFoo();
    }
    

    And more...

    TODO!

    opened by JakeWharton 106
  • How to Upload a File using Retrofit 2.0

    How to Upload a File using Retrofit 2.0

    How to upload a file using multipart/form-data upload in Retrofit 2.0, I am unable to upload and there is no proper documentation anywhere on uploading file using retrofit 2.0, I followed the docs in retrofit website but I was not able to make it work.

    All the examples I see used TypedFile. It is not clear how to use RequestBody. Please post sample code.

    opened by vivekkiran 100
  • 1.4.0 New line in String causes retrofit.RetrofitError: java.io.EOFException

    1.4.0 New line in String causes retrofit.RetrofitError: java.io.EOFException

    Gist: https://gist.github.com/mazurio/8750846

    Description is a text taken from TextView (Android), if it contains more than one new line then it causes EOFException and insert fails. Trying to figure it out now.

    I tried to escape the string. It is the same problem.

    opened by mazurio 59
  • Allow to configure retrofit to allow API interfaces to extend interfaces

    Allow to configure retrofit to allow API interfaces to extend interfaces

    The comment:

    // Prevent API interfaces from extending other interfaces. This not only avoids a bug in
    // Android (http://b.android.com/58753) but it forces composition of API declarations which is
    // the recommended pattern.
    

    in:

    https://github.com/square/retrofit/blob/master/retrofit/src/main/java/retrofit/Utils.java

    Sounds rather arbitrary. I think it should be configurable at the very least.

    I for example have something very similar to the following.

    A base response class:

    class GenericResponse {
       Boolean success
    }
    

    and an interface that defines how my API needs to be accessed:

    interface GenericAPI<R extends GenericResponse> {
       void obtainData(
          String name, String version, Map<String, String> parameters, Callback<R> callback
       )
    }
    

    I latter extend that interface with some specific API like:

    interface GetUsersAPI extends GenericAPI<UsersResponse> {
       @GET("/dataAPI/{version}/{name}")
       void obtainData(
          @Path("name") String name,
          @Path("version") String version,
          @QueryMap Map<String, String> parameters,
          Callback<UsersResponse> callback
       )
    }
    

    being UsersResponse an extension of GenericResponse. With something like that, I can implement an abstract client like:

    abstract class GenericClient<R extends GenericResponse, C extends GenericConnector> implements Callback<R> { 
    
       protected void doRequest(
          Class<C> apiDefinition, 
          String name, String version, 
          Map<String, Object> params
       ) { 
          new RestAdapter.Builder().build().create(apiDefinition).obtainData(
             name, version, params, this
          )
       }
    }
    

    That client can work with any of my APIs, avoiding code duplication while having typing enforced by the compiler using generics. It can deal with any obtainData connector and with the common parts of every response. When implemented by a concrete class, thanks to the use of generics and inheritance, the data is transformed to the proper specific response class and when using an IDE with generics support (any, I guess :) is very convenient to use every method with the signature automatically transformed to the concrete classes declared by the implementor class.

    I understand that composition is better for many things, but I don't see how to work with a generic connector the way I'm doing it, being able to assume that every connector will have an obtainData with the given parameters and having that enforced by the compiler.

    I'm not saying is not possible - I'm saying I don't know how, and the restriction I'm finding is, in my opinion, quite poorly explained.

    I think something whose reason to be is something as arguable as "composition is the only possible, good way" should be configurable at least.

    Enhancement 
    opened by deigote 40
  • Handle Empty Body

    Handle Empty Body

    After updating to retrofit beta-3 I'm getting the Exception (Because of an empty body)

    java.io.EOFException: End of input at line 1 column 1
                                                                               at com.google.gson.stream.JsonReader.nextNonWhitespace(JsonReader.java:1414)
                                                                               at com.google.gson.stream.JsonReader.doPeek(JsonReader.java:553)
                                                                               at com.google.gson.stream.JsonReader.peek(JsonReader.java:429)
                                                                               at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:202)
                                                                               at com.google.gson.TypeAdapter.fromJson(TypeAdapter.java:260)
                                                                               at retrofit2.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:33)
                                                                               at retrofit2.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:23)
                                                                               at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:154)
                                                                               at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:92)
                                                                               at okhttp3.RealCall$AsyncCall.execute(RealCall.java:133)
    

    I know that It's possible to solve this issue Using Call<Void> but is there any other way to enforce OkHttp or Gson To accept Empty body?

    Response Log:

     D/OkHttp: Date: Mon, 01 Feb 2016 08:32:10 GMT
    D/OkHttp: Server: Apache/2.4.7 (Ubuntu)
    D/OkHttp: X-Powered-By: PHP/5.5.9-1ubuntu4.13
    D/OkHttp: Expires: Thu, 19 Nov 1981 08:52:00 GMT
    D/OkHttp: Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
    D/OkHttp: Pragma: no-cache
    D/OkHttp: Access-Control-Allow-Origin: https://example.com
    D/OkHttp: Access-Control-Allow-Methods: GET,POST,OPTIONS
    D/OkHttp: Access-Control-Allow-Headers: Accept,Cache-Control,Pragma,Origin,Authorization,Content-Type,X-Requested-With,Cookie,*
    D/OkHttp: Access-Control-Allow-Credentials: true
    D/OkHttp: Content-Length: 0
    D/OkHttp: Keep-Alive: timeout=5, max=99
    D/OkHttp: Connection: Keep-Alive
    D/OkHttp: Content-Type: application/json
    D/OkHttp: OkHttp-Sent-Millis: 1454315528548
    D/OkHttp: OkHttp-Received-Millis: 1454315528725
    D/OkHttp: <-- END HTTP (0-byte body)
    
    opened by roybrener 38
  • 2.0-beta2 adding extra quotes to multipart string form values

    2.0-beta2 adding extra quotes to multipart string form values

    retrofit 2.0 seems to be double quoting strings in multi part post requsts.

    for example this interface

    public interface ApiInterface {
    
        @Multipart
        @POST("user/login/")
        Call<SessionToken> userLogin(@Part("username") String username, @Part("password") String password);
    }
    

    server side will print the key value pairs as

    username : "brian"
    password : "password"
    

    instead of

    username : brian
    password : password
    

    The second way is how it would show up in retrofit 1.9 and any other rest client.

    stack link https://stackoverflow.com/questions/33205855/retrofit-2-0-beta-2-is-adding-literal-quotes-to-multipart-values?noredirect=1#comment54246402_33205855

    opened by bperin 37
  • Add ErrorHandler for customization of RetrofitError behavior

    Add ErrorHandler for customization of RetrofitError behavior

    Add a new interface, ErrorHandler, which is responsible for throwing customized exceptions during synchronous request errors, or directing to the appropriate callback method for asynchronous request errors.

    Currently, API users must catch RetrofitError and try to determine the cause of the error based on certain properties of the HTTP response. This interface allows API clients to expose semantic exceptions to their users.

    For example, if I had an API interface method to create a User, I might expose an InvalidUserException which could be declared on the createUser method, and used to indicate that something was invalid about the request.

    This implementation allows exceptions to be checked or unchecked, leaving that decision up to the API designer. It also doesn't change any existing behavior. Let me know if there's anything I can do to clean it up!

    opened by sberan 37
  • method POST must have a request body.

    method POST must have a request body.

    Why?

    compile 'com.squareup.okhttp:okhttp:2.3.0'
    compile 'com.squareup.retrofit:retrofit:1.9.0'
    
                         D  java.lang.IllegalArgumentException: method POST must have a request body.
                            D      at com.squareup.okhttp.Request$Builder.method(Request.java:236)
                            D      at retrofit.client.OkClient.createRequest(OkClient.java:59)
                            D      at retrofit.client.OkClient.execute(OkClient.java:53)
                            D      at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:326)
                            D      at retrofit.RestAdapter$RestHandler.access$100(RestAdapter.java:220)
                            D      at retrofit.RestAdapter$RestHandler$2.obtainResponse(RestAdapter.java:278)
                            D      at retrofit.CallbackRunnable.run(CallbackRunnable.java:42)
                            D      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
                            D      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
                            D      at retrofit.Platform$Android$2$1.run(Platform.java:142)
                            D      at java.lang.Thread.run(Thread.java:818)
    
    opened by crossle 37
  • RxJava Retrofit --Fatal Exception thrown on Scheduler.Worker thread.

    RxJava Retrofit --Fatal Exception thrown on Scheduler.Worker thread.

    ApiManager.getApi().dispatchService(SPUtils.getUserId(), groupType) .observeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new ResultSubscriber() { @Override public void onSuccess(ServiceResultBean serviceResultBean) {

                        }
    
                        @Override
                        public void onError(ResultException error) {
                            name.setText(error.getMessage());
                        }
    
                        @Override
                        public void onCompleted() {
                            loading.setVisibility(View.GONE);
                        }
                    });
    

    then... E/AndroidRuntime﹕ FATAL EXCEPTION: main java.lang.IllegalStateException: Fatal Exception thrown on Scheduler.Worker thread. at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:62) at android.os.Handler.handleCallback(Handler.java:615) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4745) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) at dalvik.system.NativeStart.main(Native Method) Caused by: rx.exceptions.OnErrorFailedException: Error occurred when trying to propagate error to Observer.onError at rx.observers.SafeSubscriber._onError(SafeSubscriber.java:201) at rx.observers.SafeSubscriber.onError(SafeSubscriber.java:111) at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.pollQueue(OperatorObserveOn.java:197) at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber$2.call(OperatorObserveOn.java:170) at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)             at android.os.Handler.handleCallback(Handler.java:615)             at android.os.Handler.dispatchMessage(Handler.java:92)             at android.os.Looper.loop(Looper.java:137)             at android.app.ActivityThread.main(ActivityThread.java:4745)             at java.lang.reflect.Method.invokeNative(Native Method)             at java.lang.reflect.Method.invoke(Method.java:511)             at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)             at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)             at dalvik.system.NativeStart.main(Native Method) Caused by: rx.exceptions.CompositeException: 2 exceptions occurred.             at rx.observers.SafeSubscriber._onError(SafeSubscriber.java:201)             at rx.observers.SafeSubscriber.onError(SafeSubscriber.java:111)             at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.pollQueue(OperatorObserveOn.java:197)             at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber$2.call(OperatorObserveOn.java:170)             at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)             at android.os.Handler.handleCallback(Handler.java:615)             at android.os.Handler.dispatchMessage(Handler.java:92)             at android.os.Looper.loop(Looper.java:137)             at android.app.ActivityThread.main(ActivityThread.java:4745)             at java.lang.reflect.Method.invokeNative(Native Method)             at java.lang.reflect.Method.invoke(Method.java:511)             at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)             at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)             at dalvik.system.NativeStart.main(Native Method) Caused by: rx.exceptions.CompositeException$CompositeExceptionCausalChain: Chain of Causes for CompositeException In Order Received => at android.util.Log.getStackTraceString(Log.java:314) at android.util.Slog.e(Slog.java:77) at com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException(RuntimeInit.java:72) at u.aly.n.uncaughtException(CrashHandler.java:34) at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:693) at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:690) at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:66)             at android.os.Handler.handleCallback(Handler.java:615)             at android.os.Handler.dispatchMessage(Handler.java:92)             at android.os.Looper.loop(Looper.java:137)             at android.app.ActivityThread.main(ActivityThread.java:4745)             at java.lang.reflect.Method.invokeNative(Native Method)             at java.lang.reflect.Method.invoke(Method.java:511)             at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)             at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)             at dalvik.system.NativeStart.main(Native Method) Caused by: retrofit.RetrofitError at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:395) at retrofit.RestAdapter$RestHandler.access$100(RestAdapter.java:220) at retrofit.RestAdapter$RestHandler$1.invoke(RestAdapter.java:265) at retrofit.RxSupport$2.run(RxSupport.java:55) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:442) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) at java.util.concurrent.FutureTask.run(FutureTask.java:137) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) at retrofit.Platform$Android$2$1.run(Platform.java:142) at java.lang.Thread.run(Thread.java:856) Caused by: java.net.SocketTimeoutException at java.net.PlainSocketImpl.read(PlainSocketImpl.java:491) at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46) at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:240) at okio.Okio$2.read(Okio.java:137) at okio.AsyncTimeout$2.read(AsyncTimeout.java:211) at okio.RealBufferedSource.indexOf(RealBufferedSource.java:306) at okio.RealBufferedSource.indexOf(RealBufferedSource.java:300) at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:196) at com.squareup.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:191) at com.squareup.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:80) at com.squareup.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:917) at com.squareup.okhttp.internal.http.HttpEngine.access$300(HttpEngine.java:95) at com.squareup.okhttp.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:902) at com.squareup.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:760) at com.squareup.okhttp.Call.getResponse(Call.java:274) at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:230) at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:201) at com.squareup.okhttp.Call.execute(Call.java:81) at retrofit.client.OkClient.exec

    opened by cuimingqiang 37
  • Add a way to set filename on multipart requests

    Add a way to set filename on multipart requests

    This has already been discussed in #1063 #1092 #1096 and #1130, but I thought I'd open a separate issue to track this specifically.

    RFC2388 describes the filename header parameter of multipart/form-data requests that Retrofit now uses. This parameter is required on some backend configurations. More details and examples can be found here.

    We need a way of figuring out what the filename is. The problem with RequestBody (which is a part of OkHttp) is that it doesn't expose the filename when created with a File.

    Feature 
    opened by lukaciko 37
  • Method return type must not include a type variable or wildcard

    Method return type must not include a type variable or wildcard

    Using com.squareup.retrofit2:retrofit:2.9.0

    After upgrading gradle plugin from

    com.android.tools.build:gradle:4.1.3
    

    to

    com.android.tools.build:gradle:4.2.2
    

    I'm getting following error when running with minifyEnabled true:

    java.lang.IllegalArgumentException: Method return type must not include a type variable or wildcard
    

    Here's how looks the method, which generates the error:

        @FormUrlEncoded
        @POST("view_ad") //NON-NLS
        Call<GenericDataResponse<EmptyData>> viewAd(
                @Field("session_id") String sessionId, //NON-NLS
                @Field("id") int id //NON-NLS
        );
    
        public class EmptyData {
    
            public EmptyData(){}
    
        }
    
        public class GenericDataResponse<T> {
    
            @SerializedName("result") //NON-NLS
            public String result;
    
            @SerializedName("data") //NON-NLS
            public T data;
    
            @SerializedName("mess") //NON-NLS
            public String[] messages;
        }
    

    In order to fix this I have to either:

    • downgrade to the previous gradle plugin version
    • add proguard rule: -keep class com.example.app.EmptyData
    • disable proguard/r8

    I've read the docs about gradle 4.2 changes and nothing seems to be related to proguard directly. Can someone explain what's going on?

    opened by piotrros 9
  • Update protobuf version for converter-protobuf

    Update protobuf version for converter-protobuf

    What kind of issue is this?

    • [ ] Question. This issue tracker is not the place for questions. If you want to ask how to do something, or to understand why something isn't working the way you expect it to, use Stack Overflow. https://stackoverflow.com/questions/tagged/retrofit

    • [ ] Bug report. If you’ve found a bug, spend the time to write a failing test. Bugs with tests get fixed. Here’s an example: https://gist.github.com/swankjesse/6608b4713ad80988cdc9

    • [x] Feature Request. Start by telling us what problem you’re trying to solve. Often a solution already exists! Don’t send pull requests to implement new features without first getting our support. Sometimes we leave features out on purpose to keep the project small.

    com.google.protobuf:protoc:3.10.0 is not support Apple M1. Please update to v3.17.3 to support M1.

    https://github.com/protocolbuffers/protobuf/releases/tag/v3.17.3

    Execution failed for task ':retrofit-converters:protobuf:generateTestProto'.
    > Could not resolve all files for configuration ':retrofit-converters:protobuf:protobufToolsLocator_protoc'.
       > Could not find protoc-3.10.0-osx-aarch_64.exe (com.google.protobuf:protoc:3.10.0).
         Searched in the following locations:
             https://repo.maven.apache.org/maven2/com/google/protobuf/protoc/3.10.0/protoc-3.10.0-osx-aarch_64.exe
    
    Possible solution:
     - Declare repository providing the artifact, see the documentation at https://docs.gradle.org/current/userguide/declaring_repositories.html
    
    
    opened by jianjunhuang 0
  • V2.10 is overdue for release

    V2.10 is overdue for release

    The last stable release was 2.9.0 which is now over a year old. 2.10 has changes I rely on, so I'm having to use the 2.10.0-SNAPSHOT which has the potential for things to break unexpectedly, since it can change without notice.

    Is there a timeframe for releasing 2.10.0?

    opened by clydebarrow 4
  • WIP: BOM publishing

    WIP: BOM publishing

    Alternative to #3487

    opened by realdadfish 1
  • Added @IgnoreParameter meta annotation

    Added @IgnoreParameter meta annotation

    This is an attempt to add the custom parameter annotations ability requested #2890 in a way that is not intrusive to the existing Retrofit API surface.

    I added an @IgnoreParameter meta annotation that can be applied to any custom parameter annotation that then causes Retrofit to ignore it during processing. The developer is then free to handle the annotation in a custom request interceptor if they so choose.

    This approach preserves the behavior of any existing non Retrofit managed parameters causing Retrofit to throw an exception when building the client.

    Example Usage

    @IgnoreParameter
    @Target(PARAMETER)
    @Retention(RUNTIME)
    public @interface CustomParam { }
    
    public interface ExampleClient {
       @GET
       Call<Object> test(@CustomParam String myParam);
    }
    

    The biggest downside to this method is that it requires just-in-time handling of any custom annotations in your interceptor which is not ideal but not worse than being unable to do it in the first place in my opinion.

    I'm also not satisfied with the name. @IgnoreParameter seems a little clunky so I'm open to suggestions.

    opened by nightfire2 0
  • Using Optional as a return type with Moshi converter crashes with IllegalArgumentException

    Using Optional as a return type with Moshi converter crashes with IllegalArgumentException

    What kind of issue is this?

    • [ ] Question. This issue tracker is not the place for questions. If you want to ask how to do something, or to understand why something isn't working the way you expect it to, use Stack Overflow. https://stackoverflow.com/questions/tagged/retrofit

    • [x] Bug report. If you’ve found a bug, spend the time to write a failing test. Bugs with tests get fixed. Here’s an example: https://gist.github.com/swankjesse/6608b4713ad80988cdc9

    • [ ] Feature Request. Start by telling us what problem you’re trying to solve. Often a solution already exists! Don’t send pull requests to implement new features without first getting our support. Sometimes we leave features out on purpose to keep the project small.

    Hi, I'm trying to implement a Retrofit API with a function which returns a class wrapped in Optional and I'm using Moshi to parse the JSON. Here's the relevant source code for the interface:

    interface PostmanEchoIpApi {
        @GET("/ip")
        suspend fun getIp(): Optional<PostmanResponse>
    }
    
    @JsonClass(generateAdapter = true)
    data class PostmanResponse(val ip: String)
    

    And here is the relevant code where's it used:

    val retrofit = Retrofit.Builder()
        .baseUrl("https://postman-echo.com/")
        .addConverterFactory(MoshiConverterFactory.create())
        .build()
    val postmanEchoIpApi = retrofit.create(PostmanEchoIpApi::class.java)
    lifecycleScope.launch {
        val ip = postmanEchoIpApi.getIp()
    }
    

    But the app seems to be crashing with:

    Caused by: java.lang.IllegalArgumentException: Platform class java.util.Optional in java.util.Optional<com.test.PostmanResponse> requires explicit JsonAdapter to be registered
       at com.squareup.moshi.ClassJsonAdapter$1.create(ClassJsonAdapter.java:75)
       at com.squareup.moshi.Moshi.adapter(Moshi.java:145)
       at com.squareup.moshi.Moshi.adapter(Moshi.java:105)
       at retrofit2.converter.moshi.MoshiConverterFactory.responseBodyConverter(MoshiConverterFactory.java:89)
       at retrofit2.Retrofit.nextResponseBodyConverter(Retrofit.java:362)
       at retrofit2.Retrofit.responseBodyConverter(Retrofit.java:345)
       at retrofit2.HttpServiceMethod.createResponseConverter(HttpServiceMethod.java:124)
       at retrofit2.HttpServiceMethod.parseAnnotations(HttpServiceMethod.java:85)
       at retrofit2.ServiceMethod.parseAnnotations(ServiceMethod.java:39)
       at retrofit2.Retrofit.loadServiceMethod(Retrofit.java:202)
       at retrofit2.Retrofit$1.invoke(Retrofit.java:160)
       at java.lang.reflect.Proxy.invoke(Proxy.java:1006)
       at $Proxy3.getIp(Unknown Source)
    

    I think this is happening because the Moshi converter is added before the platform aware converter which handles the Optional type and since the Moshi converter assumes that it can handle all types, it crashes. Shouldn't the platform aware converters be added after the built-in converters but before the rest of the converters?

    I've pushed out a commit at https://github.com/tejas-n/retrofit/commit/4d3e1169f76d860a12da2262d1d112129a793e98 which seems to be fixing my issue.

    Can you let me know if this is a valid issue and the commit that I pushed out is the right way to solve it, please? I'll create a PR if that's the case.

    opened by tejas-n 0
  • Add a link to kotlin examples to the Website.

    Add a link to kotlin examples to the Website.

    What kind of issue is this?

    • [ ] Feature Request.

    For someone looking at the Website there is no way to know that retrofit supports kotlins suspend keyword.

    opened by gyrraf 0
  • Call not available for import

    Call not available for import

    I have imported retrofit2 to my App. But still, I can't import Call<>. If I try to write import statement manually also retrofit2.Call is showing errors.

    import 'com.spuareup.retrofit2:retrofit:2.9.0'

    opened by GaneshShetty951 1
  • Add R8 rules for converter-protobuf

    Add R8 rules for converter-protobuf

    What kind of issue is this?

    • [ ] Question.
    • [ ] Bug report.
    • [x] Feature Request.

    ProtoConverterFactory works by accessing the generated parser() method through reflection. If R8 is not correctly configured it will potentially remove or rename the method while doing code code shrinking or obfuscation. These days AARs and JARs can ship with the required R8 configuration which is then applied automatically. I believe it should be something like:

    -keepclassmembers public class * extends com.google.protobuf.MessageLite {
      public static ** parser();
     }
    

    The downside with this simple rule is that it would keep the parser() method of all kept MessageLite classes, even those that are not used by Retrofit. I believe that is not a significant concern for most apps. Let me know if this sounds reasonable.

    opened by lukaciko 0
  • Add support for Kotlin's Result

    Add support for Kotlin's Result

    Now that inline classes are stable in Kotlin 1.5.0, it would be nice to have API endpoints return Result to wrap the outcome (success/failure) of a retrofit call, instead of returning a value or throwing an exception.

    For example:

    @GET("me")
    suspend fun getUser(): Result<User>
    
    Feature 
    opened by GSala 2
Releases(parent-2.0.0-beta3)
:satellite: [Android Library] Simplified async networking in android

Android library that simplifies networking in android via an async http client. Also featured in [Awesome Android Newsletter #Issue 15 ] Built with ❤︎

Nishant Srivastava 35 Jul 14, 2021
HttpMocker is a simple HTTP mocking library written in Kotlin to quickly and easily handle offline modes in your apps

HttpMocker HttpMocker is a very lightweight Kotlin library that allows to mock HTTP calls relying on either OkHttp or the Ktor client libraries. It ca

David Blanc 160 Jul 5, 2021
Multiplatform coroutine-based HTTP client wrapper for Kotlin

networkinkt This is a lightweight HTTP client for Kotlin. It relies on coroutines on both JS & JVM platforms. Here is a simple GET request: val text =

Egor Zhdan 31 Jun 24, 2020
Asynchronous socket, http(s) (client+server) and websocket library for android. Based on nio, not threads.

AndroidAsync AndroidAsync is a low level network protocol library. If you are looking for an easy to use, higher level, Android aware, http request li

Koushik Dutta 7.1k Jul 31, 2021
A type-safe HTTP client for Android and the JVM

Retrofit A type-safe HTTP client for Android and Java. For more information please see the website. Download Download the latest JAR or grab from Mave

Square 38.4k Jul 28, 2021
Square’s meticulous HTTP client for the JVM, Android, and GraalVM.

OkHttp See the project website for documentation and APIs. HTTP is the way modern applications network. It’s how we exchange data & media. Doing HTTP

Square 40.5k Jul 26, 2021
🚀 A Complete Fast Android Networking Library that also supports HTTP/2 🚀

Fast Android Networking Library About Fast Android Networking Library Fast Android Networking Library is a powerful library for doing any type of netw

AMIT SHEKHAR 5.3k Aug 2, 2021
🚀 A Complete Fast Android Networking Library that also supports HTTP/2 🚀

Fast Android Networking Library About Fast Android Networking Library Fast Android Networking Library is a powerful library for doing any type of netw

AMIT SHEKHAR 5.3k Jul 26, 2021
Android client for ProjectRTC - a WebRTC demo

AndroidRTC WebRTC Live Streaming An Android client for ProjectRTC. It is designed to demonstrate WebRTC video calls between androids and/or desktop br

Chabardes 1.4k Jul 26, 2021
Kotlin DSL http client

Introduction Kotlin DSL http client Features ?? Developers Experience-driven library without verbosity. ?? Native way to use http client in Kotlin. ??

Sergei Rybalkin 444 Jul 26, 2021
This project under develop

Asynchronous Http Client for Android An asynchronous, callback-based Http client for Android built on top of Apache's HttpClient libraries. Changelog

null 10.6k Aug 2, 2021
This project under develop

Asynchronous Http Client for Android An asynchronous, callback-based Http client for Android built on top of Apache's HttpClient libraries. Changelog

null 10.6k Jul 30, 2021
Mock your datas for Okhttp and Retrofit in json format in just a few moves

okhttp-json-mock This simple library helps you mock your data for using with okhttp+retrofit in json format in just a few moves. it forwards the reque

Mad Mirrajabi 233 Jun 10, 2021
The easiest HTTP networking library for Kotlin/Android

Fuel The easiest HTTP networking library for Kotlin/Android. You are looking at the documentation for 2.x.y.. If you are looking for the documentation

Kittinun Vantasin 4k Aug 3, 2021