Skip to content

Commit

Permalink
Update readme (#15)
Browse files Browse the repository at this point in the history
* Update README.
* Update dependencies
  • Loading branch information
Fabian Alvarez authored Feb 22, 2018
1 parent f1fa72d commit 9825875
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 22 deletions.
149 changes: 130 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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<BootstrapApplication> {

### Usages
@Component.Builder
abstract class Builder extends AndroidInjector.Builder<BootstrapApplication> {

@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<BootstrapApplication> 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 <b>level</b>.
*
* @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<List<Task>, TaskCache> {
Expand All @@ -76,9 +186,9 @@ public class TaskQueryStrategy extends Repository.QueryStrategy<List<Task>, Task
}
```

Finally, last step is to `query` the newly created `Repository<Task, TaskCache>` to then act on the `Task`s information retrieved.
Finally, the last step is to `query` the newly created `Repository<Task, TaskCache>` 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:

Expand All @@ -105,7 +215,7 @@ Query<List<Task>> 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:

Expand All @@ -118,16 +228,17 @@ tasksQuery

The SAM interfaces for `Repository.Query#onSuccess` and `Repository.Query#onError` are `Consumer<T>` and `Consumer<Throwable>` 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)

## <a name="topic-contributing"></a> Contributing

Expand Down
6 changes: 3 additions & 3 deletions networking/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -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"
}

0 comments on commit 9825875

Please sign in to comment.