From 98258751e9e195536c6bbc8b0319489a47c82912 Mon Sep 17 00:00:00 2001 From: Fabian Alvarez Date: Thu, 22 Feb 2018 19:08:31 -0300 Subject: [PATCH] Update readme (#15) * Update README. * Update dependencies --- README.md | 149 +++++++++++++++++++++++++++++++++++----- networking/build.gradle | 6 +- 2 files changed, 133 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 4587a39..b862fdf 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,18 @@ The NETWORKING module provides a separation from the network tier from the rest of the project while also providing offline support capabilities. -### Usage +## Features -Import the module as alibrary in your project using Gradle: +* Fully compatible with Dagger and WOLMO Core v2. +* Perform REST API calls using a preconfigured Retrofit client +* HTTP requests logging in LogCat preconfigured +* `Time` classes handling preconfigured with Retrofit and custom serializers/deserializers +* Cache (offline) mechanisms base classes +* Repository pattern oriented architecture + +## Installation + +Import the module as a library in your project using Gradle: **root build.gradle** ```groovy @@ -29,34 +38,135 @@ dependencies { compile 'com.github.Wolox:wolmo-networking-android:master-SNAPSHOT' } ``` -Note: The above line will download the latest version of the module, if you want to run an specific version replace `master-SNAPSHOT` with `1.0.0` or any other version. Avaiable versions can be found here: [Github releases](https://github.com/Wolox/wolmo-networking-android/releases) +Note: The above line will download the latest version of the module, if you want to run a specific version replace `master-SNAPSHOT` with `2.0.0` or any other version. Available versions can be found here: [Github releases](https://github.com/Wolox/wolmo-networking-android/releases) -### Features +## How to use -* Perform REST API calls using a preconfigured Retrofit client -* HTTP requests logging in LogCat preconfigured -* `Time` classes handling preconfigured with Retrofit and custom serializers/deserializers -* Cache (offline) mechanisms base classes -* Repository pattern oriented architecture +Applications that use `wolmo-network` don't need to extend `NetworkingApplication` anymore. +WOLMO Networking provides the modules to build and configure the dependencies of `Retrofit`, `Gson` and `OkHttp`, it also provides a default `NetworkingComponent` to simplify the creation and reduce configuration on common scenarios. For it to work you only need to provide it with the `baseUrl`, an optional list of interceptors to add to okHttp and an optional list of Gson type adapters. + +This version of Networking adds the following Modules: + +* **CachingModule**: Provides all the dependencies to cache request. +* **GsonModule**: Provides a Gson instance and all the dependencies to build it. +* **OkHttpClientModule**: Provides a instance of `OkHttpClient` and all the dependencies to build it. +* **NetworkingModule**: Provides a instance of `Retrofit`. + +There are two possible ways to use it: + +### Add a component dependency to NetworkingComponent + +You can use it this way when you don't need further customizations. +```java +@ApplicationScope +@Component(dependencies = {NetworkingComponent.class}, + modules = { AndroidSupportInjectionModule.class, DefaultModule.class, + ContextModule.class, AppModule.class }) +public interface AppComponent extends AndroidInjector { -### Usages + @Component.Builder + abstract class Builder extends AndroidInjector.Builder { + + @BindsInstance + public abstract Builder application(Application application); + + public abstract Builder networkingComponent(NetworkingComponent networkingComponent); + + } +} +``` + +In your application you need to build the `NetworkingComponent` like: + +```java +public class BootstrapApplication extends WolmoApplication { + + @Override + public void onInit() { ... } + + @Override + protected AndroidInjector applicationInjector() { + return DaggerAppComponent.builder().networkingComponent(buildDaggerNetworkingComponent()) + .application(this) + .create(this); + } + + private NetworkingComponent buildDaggerNetworkingComponent() { + NetworkingComponent.Builder builder = + DaggerNetworkingComponent.builder().baseUrl(Configuration.EXAMPLE_CONFIGURATION_KEY) + .gsonNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES); + + if (BuildConfig.DEBUG) { + builder.okHttpInterceptors( + buildHttpLoggingInterceptor(Level.BODY), new ChuckInterceptor(this)); + } + + return builder.build(); + } + + /** + * Returns a {@link HttpLoggingInterceptor} with the level given by level. + * + * @param level - Logging level for the interceptor. + * @return New instance of interceptor + */ + private static HttpLoggingInterceptor buildHttpLoggingInterceptor( + @NonNull HttpLoggingInterceptor.Level level) { + HttpLoggingInterceptor loggerInterceptor = new HttpLoggingInterceptor(); + loggerInterceptor.setLevel(level); + return loggerInterceptor; + } +} +``` + +### Create a new NetworkComponent + +If you need to satisfy another dependencies or you need to change those provided by WOLMO Networking you can create your own `CustomNetworkComponent` and add only the +wanted modules from WOLMO and your own. For example: + +```java +@NetworkingScope +@Component(modules = { JacksonModule.class, OkHttpClientModule.class, NetworkingModule.class }) +public interface MyCustomNetworkingComponent { + + RetrofitServices retrofitServices(); + + @Component.Builder + interface Builder { + + @BindsInstance + Builder baseUrl(String baseUrl); + + @BindsInstance + Builder okHttpInterceptors(@Nullable Interceptor... interceptors); + + ... + + MyCustomNetworkingComponent build(); + } +} +``` + +Or you can directly add the Modules to your `AppComponent` if you wish. + +## Usages An example instantiation and usage of the `Repository` class is the following. Consider the case of an app that needs to load a set of `Task`s and wants to fetch them locally first (See `Repository.AccessPolicy` for other policies). To create the necessary `Repository` these few lines of code are needed: -``` +```java mTaskRepository = new Repository(cache, Repository.CACHE_FIRST); ``` -The `Repository.AccessPolicy` can be ommitted if you intend to use the configurable `Repository.DEFAULT_ACCESS_POLICY` as its access policy. +The `Repository.AccessPolicy` can be omitted if you intend to use the configurable `Repository.DEFAULT_ACCESS_POLICY` as its access policy. Note that the creation *requires* one thing: a `TaskCache`. We won't dwell in the details of what a `TaskCache` should be. The advantage is that it can be **anything the users of the library consider a cache**. It can be implemented atop of memory, SQLite database, a faster web service, etc. -On the other hand, a `QueryStrategy` is mechanism that defines what to do in case the `Repository` determines it should either `readLocalSource` or `consumeRemoteSource`. +On the other hand, a `QueryStrategy` is a mechanism that defines what to do in case the `Repository` determines it should either `readLocalSource` or `consumeRemoteSource`. ``` public class TaskQueryStrategy extends Repository.QueryStrategy, TaskCache> { @@ -76,9 +186,9 @@ public class TaskQueryStrategy extends Repository.QueryStrategy, Task } ``` -Finally, last step is to `query` the newly created `Repository` to then act on the `Task`s information retrieved. +Finally, the last step is to `query` the newly created `Repository` to then act on the `Task`s information retrieved. -There are 2 flavors of `Repository#query`, that each offers an overload for passing an `AccessPolicy` to use for that particular `query`. +There are 2 flavors of `Repository#query`, each offering an overload for passing an `AccessPolicy` to use for that particular `query`. * Executing the query logic immediately: @@ -105,7 +215,7 @@ Query> tasksQuery = mTaskRepository.query( }); ``` -The `Repository.Query` holds the logic of the query ready to be `Repository.Query#run`. This class implements `Runnable` which allows integration with several other APIs. +The `Repository.Query` holds the logic of the query ready to be `Repository.Query#run`. This class implements `Runnable`, which allows integration with several other APIs. This allows the users of the class to do: @@ -118,16 +228,17 @@ tasksQuery The SAM interfaces for `Repository.Query#onSuccess` and `Repository.Query#onError` are `Consumer` and `Consumer` respectively. -Important notew: We are using a custom `Customer` class. When the `Java 8` functional interfaces are supported everywhere officially, the implementation will use those. +Important note: We are using a custom `Customer` class. When the `Java 8` functional interfaces are supported everywhere officially, the implementation will use those. -The library also offers a tool to handle the 'dirty' cache common problem. Users can create `TimeResolveQueryStrategy` which already handles that case for them. Instances of this class are created with a delta time that is the time left for the local data to be considered 'clean'. When the said time has passed since the last remote data fetch, the `TimeResolveQueryStrategy` forces the remote query. +The library also offers a tool to handle the 'dirty' cache common problem. Users can create `TimeResolveQueryStrategy` which already handles that case for them. Instances of this class are created with a delta time that is the time left for the local data to be considered 'clean'. When that amount of time has passed since the last remote data fetch, the `TimeResolveQueryStrategy` forces the remote query. -### Dependencies +## Dependencies 1. [WOLMO CORE](https://github.com/Wolox/wolmo-core-android) 2. [Retrofit](https://github.com/square/retrofit) 3. [OkHTTP3](https://github.com/square/okhttp) 4. [Joda Time](http://www.joda.org/joda-time/) +5. [Dagger](https://google.github.io/dagger/android.html) ## Contributing diff --git a/networking/build.gradle b/networking/build.gradle index c61a992..aaf9e7b 100755 --- a/networking/build.gradle +++ b/networking/build.gradle @@ -34,7 +34,7 @@ coveralls { } buildscript { - ext.wolmo_version = 'v2.0.0-rc1' + ext.wolmo_version = '2.0.0' ext.retrofit_version = '2.3.0' ext.okhttp3_version = '3.9.0' ext.dagger_version = '2.13' @@ -58,7 +58,7 @@ dependencies { // Test testImplementation "junit:junit:4.12" - testImplementation "org.mockito:mockito-inline:2.11.0" // Mockito inline adds support for mocking final classes and methods - testImplementation "org.assertj:assertj-core:3.8.0" + testImplementation "org.mockito:mockito-inline:2.13.0" // Mockito inline adds support for mocking final classes and methods + testImplementation "org.assertj:assertj-core:3.9.0" testImplementation "com.squareup.okhttp3:mockwebserver:$okhttp3_version" }