A Retrofit 2 call adapter for RxJava 1.x reactive types
npx @tessl/cli install tessl/maven-com-squareup-retrofit2--adapter-rxjava@3.0.00
# Retrofit RxJava Adapter
1
2
A call adapter factory for Retrofit 2 that enables integration with RxJava 1.x reactive types (Observable, Single, Completable). This adapter allows service interface methods to return RxJava reactive types instead of Retrofit's default Call interface, supporting both synchronous and asynchronous execution with configurable threading.
3
4
## Package Information
5
6
- **Package Name**: adapter-rxjava
7
- **Maven Coordinates**: com.squareup.retrofit2:adapter-rxjava
8
- **Package Type**: maven
9
- **Language**: Java
10
- **Installation**: Add to build.gradle: `implementation 'com.squareup.retrofit2:adapter-rxjava:3.0.0'`
11
12
## Core Imports
13
14
```java
15
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
16
import retrofit2.adapter.rxjava.Result;
17
```
18
19
For creating Retrofit instances:
20
21
```java
22
import retrofit2.Retrofit;
23
```
24
25
For service method return types:
26
27
```java
28
import rx.Observable;
29
import rx.Single;
30
import rx.Completable;
31
```
32
33
## Basic Usage
34
35
```java
36
import retrofit2.Retrofit;
37
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
38
import rx.Observable;
39
import rx.Single;
40
import rx.Completable;
41
42
// Add RxJava adapter to Retrofit
43
Retrofit retrofit = new Retrofit.Builder()
44
.baseUrl("https://api.example.com/")
45
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
46
.addConverterFactory(GsonConverterFactory.create())
47
.build();
48
49
// Service interface with RxJava return types
50
interface ApiService {
51
@GET("users/{id}")
52
Observable<User> getUser(@Path("id") String userId);
53
54
@POST("users")
55
Single<User> createUser(@Body User user);
56
57
@DELETE("users/{id}")
58
Completable deleteUser(@Path("id") String userId);
59
}
60
61
// Create service and make requests
62
ApiService service = retrofit.create(ApiService.class);
63
64
// Observable request
65
service.getUser("123")
66
.subscribeOn(Schedulers.io())
67
.observeOn(AndroidSchedulers.mainThread())
68
.subscribe(
69
user -> System.out.println("User: " + user.getName()),
70
error -> System.err.println("Error: " + error.getMessage())
71
);
72
73
// Single request
74
service.createUser(newUser)
75
.subscribe(
76
createdUser -> System.out.println("Created: " + createdUser.getId()),
77
error -> System.err.println("Creation failed: " + error.getMessage())
78
);
79
80
// Completable request (no response body)
81
service.deleteUser("123")
82
.subscribe(
83
() -> System.out.println("User deleted successfully"),
84
error -> System.err.println("Deletion failed: " + error.getMessage())
85
);
86
```
87
88
## Architecture
89
90
The RxJava adapter provides three main components:
91
92
- **RxJavaCallAdapterFactory**: Factory that creates call adapters for RxJava return types
93
- **Threading Configuration**: Support for synchronous, asynchronous, and custom scheduler execution
94
- **Response Wrapping**: Three modes for handling HTTP responses and errors (direct body, Response wrapper, Result wrapper)
95
- **Type Support**: Observable, Single, and Completable reactive types from RxJava 1.x
96
97
## Capabilities
98
99
### Call Adapter Factory Creation
100
101
Factory methods for creating RxJavaCallAdapterFactory instances with different threading configurations.
102
103
```java { .api }
104
/**
105
* Returns an instance which creates synchronous observables that do not operate on any scheduler by default.
106
*/
107
public static RxJavaCallAdapterFactory create();
108
109
/**
110
* Returns an instance which creates asynchronous observables using OkHttp's internal thread pool.
111
*/
112
public static RxJavaCallAdapterFactory createAsync();
113
114
/**
115
* Returns an instance which creates synchronous observables that subscribe on the specified scheduler by default.
116
* @param scheduler The scheduler to subscribe on by default
117
* @throws NullPointerException if scheduler is null
118
*/
119
public static RxJavaCallAdapterFactory createWithScheduler(Scheduler scheduler);
120
```
121
122
### Supported Return Types
123
124
The adapter supports multiple RxJava return types with different response wrapping modes.
125
126
```java { .api }
127
// Direct body types - calls onNext with deserialized body for 2XX responses,
128
// calls onError with HttpException for non-2XX responses and IOException for network errors
129
Observable<T> getResource();
130
Single<T> getResource();
131
132
// Response wrapped types - calls onNext with Response object for all HTTP responses,
133
// calls onError only with IOException for network errors
134
Observable<Response<T>> getResourceWithResponse();
135
Single<Response<T>> getResourceWithResponse();
136
137
// Result wrapped types - calls onNext with Result object for all HTTP responses and errors,
138
// never calls onError
139
Observable<Result<T>> getResourceWithResult();
140
Single<Result<T>> getResourceWithResult();
141
142
// Completable type - discards response bodies, used for operations that only need success/failure
143
Completable performAction();
144
```
145
146
### Result Wrapper Class
147
148
A wrapper class for handling HTTP responses that captures both successful responses and errors.
149
150
```java { .api }
151
/**
152
* The result of executing an HTTP request containing either a response or error.
153
*/
154
public final class Result<T> {
155
/**
156
* Creates an error result wrapping the given throwable.
157
* @param error The error that occurred
158
* @throws NullPointerException if error is null
159
*/
160
public static <T> Result<T> error(Throwable error);
161
162
/**
163
* Creates a successful result wrapping the given response.
164
* @param response The HTTP response
165
* @throws NullPointerException if response is null
166
*/
167
public static <T> Result<T> response(Response<T> response);
168
169
/**
170
* Returns the HTTP response if successful, null if error occurred.
171
*/
172
public Response<T> response();
173
174
/**
175
* Returns the error if one occurred, null if successful.
176
* IOException indicates transport problems, other exceptions indicate unexpected failures.
177
*/
178
public Throwable error();
179
180
/**
181
* Returns true if the request resulted in an error.
182
*/
183
public boolean isError();
184
}
185
```
186
187
### HTTP Exception (Deprecated)
188
189
Legacy exception class for HTTP errors, deprecated in favor of retrofit2.HttpException.
190
191
```java { .api }
192
/**
193
* @deprecated Use retrofit2.HttpException instead
194
*/
195
@Deprecated
196
public final class HttpException extends retrofit2.HttpException {
197
public HttpException(Response<?> response);
198
}
199
```
200
201
## Error Handling
202
203
The adapter provides three different error handling patterns:
204
205
**Direct Body Types (`Observable<T>`, `Single<T>`):**
206
- Successful 2XX responses: `onNext()` called with deserialized body
207
- Non-2XX responses: `onError()` called with `HttpException`
208
- Network errors: `onError()` called with `IOException`
209
210
**Response Wrapped Types (`Observable<Response<T>>`, `Single<Response<T>>`):**
211
- All HTTP responses: `onNext()` called with `Response<T>` object
212
- Network errors only: `onError()` called with `IOException`
213
214
**Result Wrapped Types (`Observable<Result<T>>`, `Single<Result<T>>`):**
215
- All responses and errors: `onNext()` called with `Result<T>` object
216
- No `onError()` calls - use `Result.isError()` and `Result.error()` to check for failures
217
218
**Completable Type:**
219
- Success: `onCompleted()` called, response body discarded
220
- Errors: `onError()` called with appropriate exception
221
222
## Threading Configuration
223
224
**Default Behavior:** Requests execute synchronously on the calling thread.
225
226
**Asynchronous Execution:**
227
```java
228
// Using createAsync() - requests execute on OkHttp's thread pool
229
RxJavaCallAdapterFactory.createAsync()
230
```
231
232
**Custom Scheduler:**
233
```java
234
// Using createWithScheduler() - requests subscribe on specified scheduler
235
RxJavaCallAdapterFactory.createWithScheduler(Schedulers.io())
236
```
237
238
**Per-Request Threading:**
239
```java
240
// Override default threading per request
241
service.getUser("123")
242
.subscribeOn(Schedulers.computation())
243
.observeOn(AndroidSchedulers.mainThread())
244
.subscribe(/* ... */);
245
```
246
247
## Usage Examples
248
249
### Observable with Error Handling
250
251
```java
252
service.getUsers()
253
.subscribeOn(Schedulers.io())
254
.observeOn(AndroidSchedulers.mainThread())
255
.subscribe(
256
users -> {
257
// Handle successful response
258
displayUsers(users);
259
},
260
error -> {
261
if (error instanceof HttpException) {
262
HttpException httpError = (HttpException) error;
263
int code = httpError.code();
264
handleHttpError(code, httpError.message());
265
} else if (error instanceof IOException) {
266
handleNetworkError(error);
267
} else {
268
handleUnexpectedError(error);
269
}
270
}
271
);
272
```
273
274
### Single with Response Wrapper
275
276
```java
277
service.getUserWithResponse("123")
278
.subscribeOn(Schedulers.io())
279
.observeOn(AndroidSchedulers.mainThread())
280
.subscribe(
281
response -> {
282
if (response.isSuccessful()) {
283
User user = response.body();
284
displayUser(user);
285
} else {
286
handleHttpError(response.code(), response.message());
287
}
288
},
289
error -> {
290
// Only IOException for network errors
291
handleNetworkError(error);
292
}
293
);
294
```
295
296
### Observable with Result Wrapper
297
298
```java
299
service.getUserWithResult("123")
300
.subscribeOn(Schedulers.io())
301
.observeOn(AndroidSchedulers.mainThread())
302
.subscribe(result -> {
303
if (result.isError()) {
304
Throwable error = result.error();
305
if (error instanceof IOException) {
306
handleNetworkError(error);
307
} else {
308
handleUnexpectedError(error);
309
}
310
} else {
311
Response<User> response = result.response();
312
if (response.isSuccessful()) {
313
displayUser(response.body());
314
} else {
315
handleHttpError(response.code(), response.message());
316
}
317
}
318
});
319
```
320
321
### Completable for Actions
322
323
```java
324
service.deleteUser("123")
325
.subscribeOn(Schedulers.io())
326
.observeOn(AndroidSchedulers.mainThread())
327
.subscribe(
328
() -> {
329
// Success - user deleted
330
showSuccess("User deleted successfully");
331
},
332
error -> {
333
// Handle deletion error
334
if (error instanceof HttpException) {
335
HttpException httpError = (HttpException) error;
336
showError("Deletion failed: " + httpError.message());
337
} else {
338
showError("Network error during deletion");
339
}
340
}
341
);
342
```
343
344
## Types
345
346
```java { .api }
347
// Response wrapper from Retrofit core
348
public final class Response<T> {
349
public boolean isSuccessful();
350
public T body();
351
public int code();
352
public String message();
353
public Headers headers();
354
public ResponseBody errorBody();
355
}
356
357
// Scheduler from RxJava
358
public abstract class Scheduler {
359
// Used for threading configuration
360
}
361
```