54
Open Sourcing the Store What we open sourced and how you can too! Mike Nakhimovich - New York Times

Open sourcing the store

Embed Size (px)

Citation preview

Page 1: Open sourcing the store

Open Sourcing the StoreWhat we open sourced and how you can too!

Mike Nakhimovich - New York Times

Page 2: Open sourcing the store

Agenda For TodayWalkthrough of New York Times’ first Android

Open Source Library

How you can make open source a library yourself

Page 3: Open sourcing the store

Problem Set

Modern Android Apps need their data representations to be fluid and always available.

Users expect their UI experience to never be compromised (blocked) by new data loads

International users expect minimal data downloads

Page 4: Open sourcing the store

Android === Open Source

Libraries fill gaps left by framework

Network Client? OKHTTP/Retrofit

Threading/Functional Programming? RxJava

Dependency Injection? Dagger

View Bindings? Butterknife

Page 5: Open sourcing the store

Android === Open Source

Libraries fill gaps left by framework

Network Client? OKHTTP/Retrofit

Threading/Functional Programming? RxJava

Dependency Injection? Dagger

View Bindings? Butterknife

Store? Data Flow & Caching

Page 6: Open sourcing the store

Introducing Store

https://github.com/NYTimes/Store

Page 7: Open sourcing the store

A Store abstracts fetching, parsing, caching, and retrieval of data in

your application.

Page 8: Open sourcing the store

Stores are configurable and enforce uni-direcitonal data flow while

exposing data as RxJava Observables

Page 9: Open sourcing the store

Sounds Great, but how do I use them?

Page 10: Open sourcing the store

Add to build.gradle

compile 'com.nytimes.android:store:1.0.1'

Page 11: Open sourcing the store

Open A Store

Store<Article> articleStore = StoreBuilder.<Article>builder()

.open();

Page 12: Open sourcing the store

Add a fetcher

public interface Fetcher<T> {

Observable<T> fetch(BarCode barCode);

}

Store<Article> articleStore = StoreBuilder.<Article>builder()

.fetcher(barCode -> api.getArticle(barCode.getKey()))

.open();

Page 13: Open sourcing the store

Or NonObservable Fetcher

Use nonObservbleFetcher when connecting to a synchronous & non observable API

Store<Article> articleStore = StoreBuilder.<Article>builder()

.nonObservableFetcher(barCode -> api.getArticle(barCode.getKey()))

.open();

Page 14: Open sourcing the store

Call your Store with a Barcode...

BarCode barcode = new BarCode("Article", "42");

articleStore.fetch(barcode)

.subscribeOn(Schedulers.io())

.observeOn(AndroidSchedulers.mainThread())

.subscribe(new Observer<Article>() {

public void onCompleted() {}

public void onError(Throwable throwable) {//handle error} public void onNext(Article article) {//bind Article to UI}});

Page 15: Open sourcing the store

Fetch Dataflow (Unidirectional)

Same request <1min will get throttled response

Page 16: Open sourcing the store

Getting Cached Data

Page 17: Open sourcing the store

articleStore.get(barcode)

.subscribeOn(Schedulers.io())

.observeOn(AndroidSchedulers.mainThread())

.subscribe(new Observer<Article>() {

public void onCompleted() {}

public void onError(Throwable throwable) {//handle error} public void onNext(Article article) {//bind Article to UI}});

Note: if nothing cached get() will act exactly like fetch()

Getting Cached Data

Page 18: Open sourcing the store

Note: if nothing cached get() will act exactly like fetch()

Get Dataflow

Page 19: Open sourcing the store

What happens if we need to transform response?Adding a Parser

Page 20: Open sourcing the store

Adding a Parser

Store<Article> articleStore = ParsingStoreBuilder.<BufferedSource, Article>builder() .fetcher(barCode -> api.getSource(barCode.getKey()))

.parser(source -> {

try (InputStreamReader reader = new InputStreamReader(source.inputStream())) {

return gson.fromJson(reader, Article.class);

} catch (IOException e) {

throw new RuntimeException(e);} })

.open();

Page 21: Open sourcing the store

Dataflow with Parser

Page 22: Open sourcing the store

Introducing Middleware

Page 23: Open sourcing the store

Use our Middleware

Before:

.parser(source -> {

try (InputStreamReader reader = new InputStreamReader(source.inputStream())) {

return gson.fromJson(reader, Article.class);

} catch (IOException e) {

throw new RuntimeException(e);} })

Page 24: Open sourcing the store

Use our Middleware

Before:.parser(source -> {

try (InputStreamReader reader = new InputStreamReader(source.inputStream())) {

return gson.fromJson(reader, Article.class);

} catch (IOException e) {

throw new RuntimeException(e);} })

After:

.parser(new GsonSourceParser<>(gson, Article.class))

Page 25: Open sourcing the store

Disk Caching

ParsingStoreBuilder.<BufferedSource, Article>builder() .fetcher(barCode -> api.getSource(barCode.getKey())) .parser(new GsonSourceParser<>(gson, Article.class)) .persister(new Persister<BufferedSource>() { public Observable<BufferedSource> read(BarCode barCode) { return Observable.fromCallable(() -> diskCache.get(barCode)); } public Observable<Boolean> write(BarCode barCode, BufferedSource source) { diskCache.save(barCode, source); return Observable.just(true); }}) .open();

Page 26: Open sourcing the store

Dataflow with Cache

Page 27: Open sourcing the store

No Need to implement yourself

articleStore = ParsingStoreBuilder.<BufferedSource, Article>builder() .fetcher(barCode -> api.getSource(barCode.getKey())) .parser(new GsonSourceParser<>(gson, Article.class)) .persister(new SourcePersister(FileSystemFactory.create(getFilesDir()))) .open();

Page 28: Open sourcing the store

Hope you’ll use StoresAnd contribute back to the project

Page 29: Open sourcing the store

Part 2How to go from 0 to Open Source Project

Page 30: Open sourcing the store

Android Studio Create a Project

Page 31: Open sourcing the store

Add a library module

Page 32: Open sourcing the store

Add some code to library

Page 33: Open sourcing the store

Use Android Studio to create Github Project

Page 34: Open sourcing the store

Add a Descriptive Readme.md

● Who is project for?

● What was motivation for creation?

● What does it do?

● How does it do it?

Page 35: Open sourcing the store

Add a License

Page 36: Open sourcing the store

Part 2B: How to upload project to Maven Central

Page 37: Open sourcing the store

Create a Sonatype Jira Account (yes really)

Page 38: Open sourcing the store

Open A ticket to claim an organization

Page 39: Open sourcing the store

Wait for Response

Page 40: Open sourcing the store

Whats a GPG Key?

Page 41: Open sourcing the store

Use GPG to create a keyhttp://central.sonatype.org/pages/working-with-pgp-signatures.html

Page 42: Open sourcing the store

Add to top level gradle.properties (don’t check into github!)

Page 43: Open sourcing the store

Add to library module gradle.properties

Page 44: Open sourcing the store

Add to top level build.gradle

Page 45: Open sourcing the store

Add Gradle Maven Plugin & Script

https://github.com/NYTimes/Store/blob/develop/gradle/maven-push.gradle

Page 46: Open sourcing the store

Run UploadArchives task

Page 47: Open sourcing the store

Go To Nexus Staging Repo to Verify

https://oss.sonatype.org/index.html#stagingRepositories

Page 48: Open sourcing the store

Close staging Repo and Deploy to Maven Central

Page 49: Open sourcing the store

Update jira with successful first upload

Page 50: Open sourcing the store

Enable Travis

Page 51: Open sourcing the store

Add Travis.yml

Page 52: Open sourcing the store

Add Contributing.md

Page 53: Open sourcing the store

Submit a talk to GDG

Page 54: Open sourcing the store

Thanks for listening