SlideShare ist ein Scribd-Unternehmen logo
1 von 54
Open Sourcing the Store
What we open sourced and how you can too!
Mike Nakhimovich - New York Times
Agenda For Today
Walkthrough of New York Times’ first Android
Open Source Library
How you can make open source a library
yourself
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
Android === Open Source
Libraries fill gaps left by framework
Network Client? OKHTTP/Retrofit
Threading/Functional Programming? RxJava
Dependency Injection? Dagger
View Bindings? Butterknife
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
Introducing Store
https://github.com/NYTimes/Store
A Store abstracts fetching, parsing,
caching, and retrieval of data in
your application.
Stores are configurable and enforce
uni-direcitonal data flow while
exposing data as RxJava
Observables
Sounds Great, but how do I
use them?
Add to build.gradle
compile 'com.nytimes.android:store:1.0.1'
Open A Store
Store<Article> articleStore = StoreBuilder.<Article>builder()
.open();
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();
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();
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}});
Fetch Dataflow (Unidirectional)
Same request <1min will
get throttled response
Getting Cached Data
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
Note: if nothing
cached get() will act
exactly like fetch()
Get Dataflow
What happens if we
need to transform
response?
Adding a Parser
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();
Dataflow with Parser
Introducing Middleware
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);} })
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))
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();
Dataflow with Cache
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();
Hope you’ll use Stores
And contribute back to the project
Part 2
How to go from 0 to Open
Source Project
Android Studio
Create a Project
Add a library module
Add some code to library
Use Android Studio to
create Github Project
Add a
Descriptive
Readme.md
● Who is project for?
● What was motivation for creation?
● What does it do?
● How does it do it?
Add a License
Part 2B: How to upload
project to Maven Central
Create a Sonatype Jira
Account (yes really)
Open A ticket to claim an organization
Wait for Response
Whats a GPG Key?
Use GPG to create a key
http://central.sonatype.org/pages/working-with-pgp-signatures.html
Add to top level gradle.properties
(don’t check into github!)
Add to library module gradle.properties
Add to top level build.gradle
Add Gradle Maven Plugin & Script
https://github.com/NYTimes/Store/blob/develop/gradle/maven-push.gradle
Run UploadArchives task
Go To Nexus Staging Repo to Verify
https://oss.sonatype.org/index.html#stagingRepositories
Close staging Repo and Deploy to Maven Central
Update jira with successful
first upload
Enable Travis
Add Travis.yml
Add Contributing.md
Submit a talk to GDG
Thanks for listening

Weitere ähnliche Inhalte

Was ist angesagt?

Was ist angesagt? (20)

Spring Boot Actuator 2.0 & Micrometer #jjug_ccc #ccc_a1
Spring Boot Actuator 2.0 & Micrometer #jjug_ccc #ccc_a1Spring Boot Actuator 2.0 & Micrometer #jjug_ccc #ccc_a1
Spring Boot Actuator 2.0 & Micrometer #jjug_ccc #ccc_a1
 
A friend in need - A JS indeed
A friend in need - A JS indeedA friend in need - A JS indeed
A friend in need - A JS indeed
 
Testing in android
Testing in androidTesting in android
Testing in android
 
GKAC 2015 Apr. - RxAndroid
GKAC 2015 Apr. - RxAndroidGKAC 2015 Apr. - RxAndroid
GKAC 2015 Apr. - RxAndroid
 
Android dev toolbox
Android dev toolboxAndroid dev toolbox
Android dev toolbox
 
FullStack Reativo com Spring WebFlux + Angular
FullStack Reativo com Spring WebFlux + AngularFullStack Reativo com Spring WebFlux + Angular
FullStack Reativo com Spring WebFlux + Angular
 
Serverless Angular, Material, Firebase and Google Cloud applications
Serverless Angular, Material, Firebase and Google Cloud applicationsServerless Angular, Material, Firebase and Google Cloud applications
Serverless Angular, Material, Firebase and Google Cloud applications
 
Speed up your GWT coding with gQuery
Speed up your GWT coding with gQuerySpeed up your GWT coding with gQuery
Speed up your GWT coding with gQuery
 
Angular 2 introduction
Angular 2 introductionAngular 2 introduction
Angular 2 introduction
 
End to end todo list app with NestJs - Angular - Redux & Redux Saga
End to end todo list app with NestJs - Angular - Redux & Redux SagaEnd to end todo list app with NestJs - Angular - Redux & Redux Saga
End to end todo list app with NestJs - Angular - Redux & Redux Saga
 
Under the Hood: Using Spring in Grails
Under the Hood: Using Spring in GrailsUnder the Hood: Using Spring in Grails
Under the Hood: Using Spring in Grails
 
Under the Hood: Using Spring in Grails
Under the Hood: Using Spring in GrailsUnder the Hood: Using Spring in Grails
Under the Hood: Using Spring in Grails
 
Quick start with React | DreamLab Academy #2
Quick start with React | DreamLab Academy #2Quick start with React | DreamLab Academy #2
Quick start with React | DreamLab Academy #2
 
Easy REST APIs with Jersey and RestyGWT
Easy REST APIs with Jersey and RestyGWTEasy REST APIs with Jersey and RestyGWT
Easy REST APIs with Jersey and RestyGWT
 
Creating a WYSIWYG Editor with React
Creating a WYSIWYG Editor with ReactCreating a WYSIWYG Editor with React
Creating a WYSIWYG Editor with React
 
Dagger 2 - Injeção de Dependência
Dagger 2 - Injeção de DependênciaDagger 2 - Injeção de Dependência
Dagger 2 - Injeção de Dependência
 
Android Developer Toolbox 2017
Android Developer Toolbox 2017Android Developer Toolbox 2017
Android Developer Toolbox 2017
 
Integrating React.js with PHP projects
Integrating React.js with PHP projectsIntegrating React.js with PHP projects
Integrating React.js with PHP projects
 
Retrofit Technology Overview by Cumulations Technologies
Retrofit Technology Overview by Cumulations TechnologiesRetrofit Technology Overview by Cumulations Technologies
Retrofit Technology Overview by Cumulations Technologies
 
Nestjs MasterClass Slides
Nestjs MasterClass SlidesNestjs MasterClass Slides
Nestjs MasterClass Slides
 

Ähnlich wie Open sourcing the store

OSGi and Spring Data for simple (Web) Application Development - Christian Bar...
OSGi and Spring Data for simple (Web) Application Development - Christian Bar...OSGi and Spring Data for simple (Web) Application Development - Christian Bar...
OSGi and Spring Data for simple (Web) Application Development - Christian Bar...
mfrancis
 
China Science Challenge
China Science ChallengeChina Science Challenge
China Science Challenge
remko caprio
 

Ähnlich wie Open sourcing the store (20)

It's always your fault
It's always your faultIt's always your fault
It's always your fault
 
Data Seeding via Parameterized API Requests
Data Seeding via Parameterized API RequestsData Seeding via Parameterized API Requests
Data Seeding via Parameterized API Requests
 
Adding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsAdding a modern twist to legacy web applications
Adding a modern twist to legacy web applications
 
Springboot2 postgresql-jpa-hibernate-crud-example with test
Springboot2 postgresql-jpa-hibernate-crud-example with testSpringboot2 postgresql-jpa-hibernate-crud-example with test
Springboot2 postgresql-jpa-hibernate-crud-example with test
 
Advanced JavaScript
Advanced JavaScriptAdvanced JavaScript
Advanced JavaScript
 
OSGi and Spring Data for simple (Web) Application Development - Christian Bar...
OSGi and Spring Data for simple (Web) Application Development - Christian Bar...OSGi and Spring Data for simple (Web) Application Development - Christian Bar...
OSGi and Spring Data for simple (Web) Application Development - Christian Bar...
 
OSGi and Spring Data for simple (Web) Application Development
OSGi and Spring Data  for simple (Web) Application DevelopmentOSGi and Spring Data  for simple (Web) Application Development
OSGi and Spring Data for simple (Web) Application Development
 
Full Stack Scala
Full Stack ScalaFull Stack Scala
Full Stack Scala
 
Web Dev 21-01-2024.pptx
Web Dev 21-01-2024.pptxWeb Dev 21-01-2024.pptx
Web Dev 21-01-2024.pptx
 
Building Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJavaBuilding Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJava
 
Apache Aries Blog Sample
Apache Aries Blog SampleApache Aries Blog Sample
Apache Aries Blog Sample
 
User Interface
User InterfaceUser Interface
User Interface
 
Reactive Java Programming: A new Asynchronous Database Access API by Kuassi M...
Reactive Java Programming: A new Asynchronous Database Access API by Kuassi M...Reactive Java Programming: A new Asynchronous Database Access API by Kuassi M...
Reactive Java Programming: A new Asynchronous Database Access API by Kuassi M...
 
Data access
Data accessData access
Data access
 
Lec6 ecom fall16
Lec6 ecom fall16Lec6 ecom fall16
Lec6 ecom fall16
 
Java 7 & 8 New Features
Java 7 & 8 New FeaturesJava 7 & 8 New Features
Java 7 & 8 New Features
 
Python reliable delivery
Python reliable deliveryPython reliable delivery
Python reliable delivery
 
China Science Challenge
China Science ChallengeChina Science Challenge
China Science Challenge
 
SgCodeJam24 Workshop
SgCodeJam24 WorkshopSgCodeJam24 Workshop
SgCodeJam24 Workshop
 
React mit TypeScript – eine glückliche Ehe
React mit TypeScript – eine glückliche EheReact mit TypeScript – eine glückliche Ehe
React mit TypeScript – eine glückliche Ehe
 

Kürzlich hochgeladen

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 

Kürzlich hochgeladen (20)

Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 

Open sourcing the store

Hinweis der Redaktion

  1. First part of the talk will be a quick primer in a new library that we released at NY Times Second part will be how to open source a library yourself.
  2. If we ever fetched data when online, we should be able
  3. Android Framework give us components like Activities, Services, Adapters and Widgets Open Source Libraries try to fill the gap Retrofit - Defacto standard for networking RxJava - Threading and functional programming Dagger - Dependecy Injection and Code Organization Butterknife - Boilerplate reduction
  4. Android Framework give us components like Activities, Services, Adapters and Widgets Open Source Libraries try to fill the gap Retrofit - Defacto standard for networking RxJava - Threading and functional programming Dagger - Dependecy Injection and Code Organization Butterknife - Boilerplate reduction
  5. Github link so that you all can check it out
  6. Store’s follow the repository pattern and try to abstract working with data into a few public methods. You ask a store for data and it gets it from either local storage or network. If data needs to be parsed, the store takes care of that as well.
  7. Store’s follow the repository pattern and try to abstract working with data into a few public methods. You ask a store for data and it gets it from either local storage or network. If data needs to be parsed, the store takes care of that as well.
  8. Store’s follow the repository pattern and try to abstract working with data into a few public methods. You ask a store for data and it gets it from either local storage or network. If data needs to be parsed, the store takes care of that as well.
  9. Each store is a representation of a single data call
  10. Each store is a representation of a single data call
  11. A fetcher will tell your Store how to load data. Think of a store as a wrapper for a particular endpoint you want to superpower. The nice part of using Stores is that it will work with both observable and non observable data sources
  12. A fetcher will tell your Store how to load data. Think of a store as a wrapper for a particular endpoint you want to superpower. The nice part of using Stores is that it will work with both observable and non observable data sources
  13. Stores use barcode to identify data, we will first create a barcode and then pass it to the store. When we subscribe to the store, it will call the fetcher and return to use an observable of the data
  14. Uni Direct
  15. Besides fetch you can also call get method on store. Calling get will return cached data if it is available rather than hitting your fetcher
  16. Walk user through new data flow
  17. Data usually comes in a format different from what UI expects. Stores have the ability to have a parser as well. Talk about the different builder & extra generic
  18. The parsing step looks generic maybe we can do something about it? We created some parsers that are shared between different stores. Here you see an example of a GsonSourceParser which takes an input of a buffered source and outputs a POJO. We also included GsonStringParser and GsonStreamParser
  19. The parsing step looks generic maybe we can do something about it? We created some parsers that are shared between different stores. Here you see an example of a GsonSourceParser which takes an input of a buffered source and outputs a POJO. We also included GsonStringParser and GsonStreamParser
  20. Just like a Fetcher and Persister, You can implement a Perisister.
  21. Don’t want to implement a persister? You don’t have to as long as you start with a BufferedSource.