-
Notifications
You must be signed in to change notification settings - Fork 662
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature 216/move converter #218
Feature 216/move converter #218
Conversation
return this; | ||
} | ||
|
||
public <T> Builder withResponseFieldMapper(@Nonnull Class type, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will be removed in next PR, as we drop support of interfaces
return this; | ||
} | ||
|
||
public Builder withResponseFieldMappers(@Nonnull Map<Type, ResponseFieldMapper> mappers) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will be removed in next PR, as we drop support of interfaces
|
||
Call httpCall = callFactory.newCall(request); | ||
if (callRef.compareAndSet(null, httpCall)) { | ||
httpCall.enqueue(new okhttp3.Callback() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So it will be scheduled to be executed on okhttp3.Dispatcher
that has own ExecutorService
.withCustomTypeAdapter(CustomType.DATETIME, dateCustomTypeAdapter) | ||
.build()) | ||
.okHttpClient(new OkHttpClient.Builder().build()) | ||
.withResponseFieldMapper(AllPlanets.class, new AllPlanets.Data.Mapper(AllPlanets.Data.FACTORY)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
with next PR these mapper registrations won't be needed at all.
import static com.apollographql.android.Utils.checkNotNull; | ||
|
||
/** TODO */ | ||
public final class ApolloClient { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should implement something like
interface Factory {
ApolloCall newCall(Operation operation);
}
This would keep client stateless. Instead ApolloCall
is an interface similar to Okhttp3.Call
which can actually do exection
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to make it implement Factory, now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't need but would be nice to have interface that defines that ApolloClient is a factory that creates ApolloCall. In case we ever want to migrate to another Client that can also produce ApolooCall
import okhttp3.RequestBody; | ||
import okio.Buffer; | ||
|
||
final class HttpOperationRequest<T extends Operation.Data> implements OperationRequest<T> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's move all this to a RealApolloCall
which implements ApolloCall
, you can model that after okhttp3.RealCall which imlpements okhttp3.Call below
public interface Call extends Cloneable {
/** Returns the original request that initiated this call. */
Request request();
/**
* Invokes the request immediately, and blocks until the response can be processed or is in
* error.
*
* <p>The caller may read the response body with the response's {@link Response#body} method. To
* avoid leaking resources callers must {@linkplain ResponseBody close the response body}.
*
* <p>Note that transport-layer success (receiving a HTTP response code, headers and body) does
* not necessarily indicate application-layer success: {@code response} may still indicate an
* unhappy HTTP response code like 404 or 500.
*
* @throws IOException if the request could not be executed due to cancellation, a connectivity
* problem or timeout. Because networks can fail during an exchange, it is possible that the
* remote server accepted the request before the failure.
* @throws IllegalStateException when the call has already been executed.
*/
Response execute() throws IOException;
/**
* Schedules the request to be executed at some point in the future.
*
* <p>The {@link OkHttpClient#dispatcher dispatcher} defines when the request will run: usually
* immediately unless there are several other requests currently being executed.
*
* <p>This client will later call back {@code responseCallback} with either an HTTP response or a
* failure exception.
*
* @throws IllegalStateException when the call has already been executed.
*/
void enqueue(Callback responseCallback);
/** Cancels the request, if possible. Requests that are already complete cannot be canceled. */
void cancel();
/**
* Returns true if this call has been either {@linkplain #execute() executed} or {@linkplain
* #enqueue(Callback) enqueued}. It is an error to execute a call more than once.
*/
boolean isExecuted();
boolean isCanceled();
/**
* Create a new, identical call to this one which can be enqueued or executed even if this call
* has already been.
*/
Call clone();
interface Factory {
Call newCall(Request request);
}
}
|
||
import javax.annotation.Nullable; | ||
|
||
public interface OperationRequest<T extends Operation.Data> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ApolloCall
|
||
private Response<T> parse(okhttp3.Response response) throws IOException { | ||
int code = response.code(); | ||
if (code < 200 || code >= 300) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you probably could use: https://square.github.io/okhttp/3.x/okhttp/okhttp3/Response.html#isSuccessful--
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
purposefully excluding 300 and up...my bad...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like it :-)
@@ -18,6 +21,10 @@ public boolean isSuccessful() { | |||
return errors == null || errors.isEmpty(); | |||
} | |||
|
|||
@Nonnull public Operation getOperation() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick - if there is no setOperation I don't think the get
prefix is necessary
.build(); | ||
|
||
Call call = callFactory.newCall(request); | ||
if (callRef.compareAndSet(null, call)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this necessary with implementation of call.execute being
@Override public Response execute() throws IOException {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
try {
client.dispatcher().executed(this);
Response result = getResponseWithInterceptorChain();
if (result == null) throw new IOException("Canceled");
return result;
} finally {
client.dispatcher().finished(this);
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes we need this as RealApolloCall keeps ref on okhttp3.Call in order to cancel request.
@@ -42,7 +42,7 @@ class ApolloPlugin implements Plugin<Project> { | |||
project.getGradle().addListener(new DependencyResolutionListener() { | |||
@Override | |||
void beforeResolve(ResolvableDependencies resolvableDependencies) { | |||
compileDepSet.add(project.dependencies.create("com.apollographql.android:api:${VersionKt.VERSION}")) | |||
compileDepSet.add(project.dependencies.create("com.apollographql.android:api:0.2.1")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to make plugin test happy, as now they are failing due to missing new snapshot verion
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok but can't merge this way or it will make snapshot like this
} | ||
|
||
apply from: rootProject.file('gradle/gradle-mvn-push.gradle') | ||
|
||
tasks.withType(Checkstyle) { | ||
exclude '**/BufferedSourceJsonReader.java' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why excluded?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because checkstyle will fail and BufferedSourceJsonReader was copied from retrofit as is without modification (we need it for ResponseReader)
|
||
void cancel(); | ||
|
||
<T extends Operation.Data> Response<T> execute() throws IOException; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nullability annotation on return value
|
||
<T extends Operation.Data> ApolloCall enqueue(@Nullable Callback<T> callback); | ||
|
||
ApolloCall clone(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ApolloCall clone(); | ||
|
||
public interface Callback<T extends Operation.Data> { | ||
void onResponse(Response<T> response); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nullability on both methods
import javax.annotation.Nonnull; | ||
|
||
public interface ApolloCallFactory { | ||
<T extends Operation> ApolloCall newCall(@Nonnull T operation); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nullability
} | ||
} | ||
|
||
@Override public <T extends Operation.Data> Response<T> execute() throws IOException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nullability (I'm really calling out only public api methods)
return parseHttpResponse(httpCall.execute()); | ||
} | ||
|
||
@Override public <T extends Operation.Data> ApolloCall enqueue(final Callback<T> callback) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same
👍 @brianPlummer mind taking a 1 over again? |
build.gradle
Outdated
@@ -31,7 +29,8 @@ ext { | |||
spock: 'org.spockframework:spock-core:0.7-groovy-2.0', | |||
truth: 'com.google.truth:truth:0.30', | |||
mockWebServer: 'com.squareup.okhttp3:mockwebserver:3.5.0', | |||
okhttpLoggingInterceptor: 'com.squareup.okhttp3:logging-interceptor:3.5.0' | |||
okhttpLoggingInterceptor: 'com.squareup.okhttp3:logging-interceptor:3.5.0', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be 3.6.0 as well....feel free to leave it if you want...i can make this an okhttp version var
+1 looks great! good work! :) |
Closes #216
First version of
ApolloClient
.Api:
<T extends Operation> ApolloCall newCall(@Nonnull T operation)
Usage (will be scheduled on okhttp3.Dispatcher#executorService):
Or (sync call)