SlideShare une entreprise Scribd logo
1  sur  58
Télécharger pour lire hors ligne
By @FinistSeb and @LostInBrittany
Sebastien Lambour
Le développeur de l'Est le plus à l'Ouest !
Java & C++ Developer, coding addict,
continuous intégration ayatollah
● Senior Software Engineer
currently, Crédit Mutuel Arkea
● FinistJug actif member
BreizhBeans community and commiter
sebastien.lambour@gmail.com
+sebastien.lambour
@FinistSeb
Horacio Gonzalez
Spaniard lost in Brittany, Java developer,
dreamer and all-around geek
● Senior Software Engineer at Crédit Mutuel Arkea
○ Currently...
● Leader of the FinistJUG and the
BreizhBeans community
http://lostinbrittany.org/
+Horacio.Gonzalez
@LostInBrittany
BreizhBeans

Developer community at the far end
of French Brittany

http://breizhbeans.org/
@BreizhBeans
Why ?

I help to create a startup
on social translation, would
you code with me ?

Great, I do the backend!
How many members?
Some 30.000 - 50.000
will be fine!
Ouch, is it not too small?
I like big toys!!!!

Nexus 4

Me too!
Let's think big then
OK, it will rock !
Backends
They often look like that !
Transforming it is HARD !
Next challenge :
Granite aircraft !!
A sexy backend?
Let's groom it!

Light weight

Data Driven

Java
Cloud Ready

OK, go around...

Test
driven
Scalable
Following the beaten track
Brainless route
JSF 2.0

Hibernate
Spring CRUD
(Create, Read, Update,Delete)

SQL

JPA
CXF

The usual suspects...
Booooooring...
And ineffective

Let's use it!
Design choices
Because we need some solid roots
Core principles
What do we want our backend to be?
●

Scalability
○

●

Adaptability
○

●

Because you want to be sure that your code works!

NoSQL (meaning Not Only SQL)
○

●

Because your business evolves, and your backend need to evolve
with it!

Testability
○

●

Because traffic growth should be a blessing, not a problem!

Because you need not only tables and foreign keys, but non-SQL
stores, search indexes, caches...

Productivity
○

Because the other 4 doesn't matter if you need to spend 4
working days to modify a service...
A first choice :
Apache Thrift
« Software framework for scalable and performant crosslanguage services development »
●
●
●
●
●

Interface description language
Multi-language code generation
Serialisation/deserialisation
RPC Framework
High performance
○ On transport layer
○ On data manipulation
Thrift, it's cool
Thrift boots productivity!
A second choice :
MongoDB
● We needed a NO-SQL store for documents
● We wanted to use Cassandra
○ Cassandra & Thrift, a love story
● We wanted a PaaS-ready backend
○ Neither Cloudbees nor Cloudfoundry supported Cassandra
○ But they supported MongoDB
● We loved MongoDB
○ Document DB are great for document oriented applications
ThriftMongoBridge
Because we wanted both
Thrift and MongoDB
Thrift rocks and works
But...
How to put Thrift objects into MongoDB ?
First bad idea!
Use Spring Data or Morphia

Thrift object mapping is bad !
Damned!

First bad idea!
Second bad idea !
Use the Mongo Driver JSON parsing

Deserialisation will be a bit hard...
Damned !

Second bad idea!
Thrift isn't cool anymore ?
We need a new idea !
Thrift, it's cool !
But we had work to do...
Write a TBSONProtocol !

The ThriftMongoBridge is born !
What does it do ?
POJO generated by the Thrift compiler
public class AnotherThrift implements org.apache.thrift.TBase... {
...
public String anotherString;
public int anotherInteger;

Thrift IDL
struct AnotherThrift {
1:string anotherString,
2:i32
anotherInteger,
}

Compile to

...
public static final Map<_Fields, org.apache.thrift.meta_data.
FieldMetaData> metaDataMap;
....
public void read(org.apache.thrift.protocol.TProtocol iprot)...
...
public void write(org.apache.thrift.protocol.TProtocol oprot) ......;
}

TBSonSerializer

TBSonProtocol

Write To BSON

TBSonDeSerializer

Read from BSON
{anotherString:"value", anotherInteger:69}
Really simple to use
Too simple ?
AnotherThrift anotherThrift = new AnotherThrift();
anotherThrift.setAnotherString("value");
anotherThrift.setAnotherInteger(69);
// serialize into DBObject
DBObject dbObject = ThriftMongoHelper.thrift2DBObject(anotherThrift);

{anotherString:"value", anotherInteger:69}
How it works
write(protocol)

Thrift object generated

TBSONSerializer

TBase

getResult
sentense directives
(begin / end)
push

Data
(read / write)

pop

Struct context
DBObject
Context Stack

TBSONProtocol

DBObject (BSON)
MongoDB object
The BreizhCamp demo
Because you want to see some code,
don't you?
The BreizhCamp demo
Given this Thrift model & service
struct BreizhCampEvent {
1:i64 date,
2:string startTime,
3:string endTime,
4:com.breizhbeans.backend.thrift.enums.model.EventTypes type,
5:string room,
6:string resume,
7:string details,
8:list<string> speakers
9:list<com.breizhbeans.backend.thrift.enums.model.Track> tracks,
}
service ProgramService {
com.....GetProgramResponse getProgram(1:com.....GetProgramRequest request)
throws (1:com....TechnicalException texp, 2:com...FunctionalException fexp)
}
struct GetProgramRequest {
1:com.breizhbeans.backend.thrift.enums.model.Track track,
2:com.breizhbeans.backend.thrift.enums.model.EventTypes type,
3:string room,
4:list<string> speakers,
}
struct GetProgramResponse {
1:list<com.breizhbeans.backend.thrift.model.BreizhCampEvent> events,
}
The BreizhCamp demo
First : Write a test

● One loader by collection
● One goal : Have Human readable test ;-)
● Manage automatically data insertion before test and
clean up after test

Application code to test

@Test
public void testGetEvents() throws Exception {

List<BreizhCampEvent> actualEvents = programDao.getEvent();
List<BreizhCampEvent> expectedEvents = new ArrayList<BreizhCampEvent>();
expectedEvents.add(getEventPimpMyBackend());
Assert.assertEquals(expectedEvents, actualEvents);
}

Expected data building
(used by the test and the
data loader)
Standard JUnit assertion
The BreizhCamp demo
Write a DAO
public List<BreizhCampEvent> getEvent() throws TechnicalException {
DBCursor cursor = null;
try {
List<BreizhCampEvent> events = new ArrayList<BreizhCampEvent>();
DBCollection collection = db.getCollection(collectionName);
DBObject query = new BasicDBObject();
// execute the query

retrieve DB collection

cursor = collection.find(query);
while(cursor.hasNext()) {

Build and execute the Query

events.add( (BreizhCampEvent) ThriftMongoHelper.DBObject2Thrift(cursor.next()));
}
return events;
} catch (Exception e) {
throw new H4TTechnicalException("Unexpected error", e, null);

Deserialize Thrift objects

} finally {
cursor.close();
}

Error handling

}

Never forget it ;-)
The BreizhCamp demo
Can I update thrift Object by code?
@Override
public BreizhCampEvent updateRoom(final BreizhCampEvent event) throws TechnicalException {
try {
BasicDBObject updateQuery = new BasicDBObject();

Mongo Update Query

updateQuery.append("$set", new BasicDBObject()
.append(getFields(BreizhCampEvent._Fields.ROOM), event.getRoom()));
db.getCollection(collectionName)
.update(getPrimaryKeyRequest(event), updateQuery)
.getLastError()

Thrift structure mapping

.throwOnError();
return event;
} catch (Exception e) {

Query execution
throw new H4TTechnicalException("Unexpected error", e, ObjectUtils.toString(event));
}
}

Error handling
The BreizhCamp demo
Can I update thrift Object by script?
Mongo DB Bson writed : > db.program.find();
{ "_id" : "id=10", "date" : NumberLong("-56433978000000"), "startTime" :
"14:45", "endTime" : "15:40", "type" : 4, "room" : "Bréhat", "resume" :
"Pimp my backend!", "details" : "Le frontend, le frontend......
...", "speakers" : [ "Sébastien Lambour", "Horacio Gonzalez" ], "tracks"
: [ 7 ], "id" : 10, "classname" : "com.breizhbeans.backend.thrift.model.
BreizhCampEvent" }

Update the field room :> db.program.update();
{ "id": 10}, { $set: { "room": "Ouessant" } }
And the perfs?
Because speed matters!
Talking about perfs
The candidates are ...

Spring Data
Morphia
And...
ThriftMongoBridge, of course
Spring Data vs
ThriftMongoBridge
● Write and Read 500 objects into MongoDB.
● Each document is composed with a List<> and a Set<>
of 500 objects.

● The document have a JSON size of 91613 bytes

Who will win ?
Code
ThriftMongoBridge
First
// Get a collection
DBCollection collection = db.getCollection("dummyColl");

Write
// Serialize the Thrift object
DBObject dbObject = ThriftMongoHelper.thrift2DBObject(thriftObject);
// Put the document
collection.insert(dbObject);

Read
DBCursor cursorDoc = collection.find();
while (cursorDoc.hasNext()) {
DBObject dbObject = cursorDoc.next();
ThriftObject thirftObject = (ThriftObject)ThriftMongoHelper.DBObject2Thrift(dbObject);
}
Code
Spring Data
First
// Retrieve the MongoOperations bean
MongoOperations mongoOperation =
(MongoOperations) ctx.getBean("mongoTemplate");

Write
// Serialize the Thrift object
mongoOperation.save(springObject, "springObject");

Read
List<SpringObject> listUser =
mongoOperation.findAll(SpringObject.class, "springObject");
Time to run !
Thrift over MongoDB rocks!
We need a logo for our OpenSource library...

Available now :

2.0
https://github.com/BreizhBeans/ThriftTools
A storage library
a backend is not,
young padawan
Because we need more things
At the beginning...
Pretty layers, neatly isolated,
like a Care Bears' birthday cake
Later in the project
Like a cake after an earthquake
And in the end...
As pretty as a British pudding...
and almost as tasty
Be Layer less
Now build the Backend !

le

b
ha
c
rea

un

● Each package have a goal
● NO package assembly rules
● Improve the complexity detection by dependencies
analysis

Goal : Fight against the "God classes" anti-pattern

m
ea
dr
Thrift services
Prevent protocol rupture, have a stable services signature.
com.h4t.CheckAccessResponse checkAccess
(1:com.h4t.CheckAccessRequest request) throws
(1:com.h4t.TechnicalException texp, 2:com.h4t.FunctionalException fexp)

stable method signature
Integrate this into
the backend
Thrift IFace implementation
Request / Response decapsulation + log & monitoring

Core Business code

Thrift object
read

write
ThriftMongoHelper
Mongo
Opérations

Query
DBObject

DBObject

Mongo Driver
Inversion of control
Keep simple too !
Prefer static dependencies injection.
Time to do the choice
or
Inversion of control
Why
Because

?
and

○ binding of the MongoDB service by the cloud
○ no production configuration required
○ only one war
Testability
Because without tests
you need faith
Test strategy
No compromise!
The rules are simple... no exception!
TDD is my religion
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.

Execute test without setup
Execute test with your build tool
Execute test into your IDE
No injection into test framework
Reuse only application injection
Keep it simple (repeat it 7 times)
Have a loose coupling (test the smallest parts)
Test must be deterministic and reproducible
Do pair review with the tests
If the complexity is growing up refactor now
...
11. If a rule goes wrong, rewrite it !
From concept to reality
Load thrift object
with preset datas
into MongoDB

Get expected
Thift object
with preset
datas

Collection Loader

Thrift DataSet

ThriftMongoTestTools

Get a Thrift object from
MongoDB related to a
unique key
Tests have goals
DAO : Validate queries and set up the test data loaders
IFACE : Functional tests
SERVICE : Test a business centric service
TU : Unit test not related to the business (test first
approach)
Tests are Data Driven
@Before
public void setUp() throws Exception {

Inject Data into MongoDB

eventLoader.load(getEventPimpMyBackend());
}
private BreizhCampEvent getEventPimpMyBackend() throws Exception {
String details = "Le frontend, le frontend... .....";
BreizhCampEvent event = eventLoader.getExpected(10, "14/06/2013", "14:45", "15:
40", EventTypes.CONF, "Bréhat", "Pimp my backend!", details);
event = eventLoader.addSpeakers(event, "Sébastien Lambour", "Horacio Gonzalez");
event = eventLoader.addTracks(event, Track.CLOUD);
return event;
}

Build test Data with java code, files, BDD
or the MongoThrift Test tools (not
opensourced yet ;-) )
What's next?
Because our work is not completed... yet!
Why integrate our lib ?
#Pragmatism
●
●
●
●

Productivity oriented
Fully testable
Container less (no servlet dependencies)
Open Source : Apache 2.0

The ThriftMongoBackend Core model will born soon !
With a name: TINAF
(ThriftMongoBackend Is Not A Framework)
What's next ?
● monitoring Thrift services in the cloud
● load tests with vmware & 10gen
● contribute TINAF
● Develop a thrift service valve to ensure brandwitdth for
critical services
Thank you !

Contenu connexe

En vedette

Enib cours c.a.i. web - séance #5 : td grails
Enib   cours c.a.i. web - séance #5 : td grailsEnib   cours c.a.i. web - séance #5 : td grails
Enib cours c.a.i. web - séance #5 : td grailsHoracio Gonzalez
 
ENIB cours CAI Web - Séance 4 - Frameworks/Spring - Cours
ENIB cours CAI Web - Séance 4 - Frameworks/Spring - CoursENIB cours CAI Web - Séance 4 - Frameworks/Spring - Cours
ENIB cours CAI Web - Séance 4 - Frameworks/Spring - CoursHoracio Gonzalez
 
Introduction au langage de script Groovy
Introduction au langage de script GroovyIntroduction au langage de script Groovy
Introduction au langage de script GroovyEric Reboisson
 
L'approche par regles metier
L'approche par regles metierL'approche par regles metier
L'approche par regles metiersenejug
 
Introduction Groovy / Grails - Cyril Picat - December 2009
Introduction Groovy / Grails - Cyril Picat - December 2009Introduction Groovy / Grails - Cyril Picat - December 2009
Introduction Groovy / Grails - Cyril Picat - December 2009JUG Lausanne
 
Présentation Groovy
Présentation GroovyPrésentation Groovy
Présentation GroovyJS Bournival
 
Tests de performances d'une application Java EE
Tests de performances d'une application Java EETests de performances d'une application Java EE
Tests de performances d'une application Java EEAntonio Gomes Rodrigues
 
Cours design pattern m youssfi partie 8 stat, template method, command , medi...
Cours design pattern m youssfi partie 8 stat, template method, command , medi...Cours design pattern m youssfi partie 8 stat, template method, command , medi...
Cours design pattern m youssfi partie 8 stat, template method, command , medi...ENSET, Université Hassan II Casablanca
 
Java entreprise edition et industrialisation du génie logiciel par m.youssfi
Java entreprise edition et industrialisation du génie logiciel par m.youssfiJava entreprise edition et industrialisation du génie logiciel par m.youssfi
Java entreprise edition et industrialisation du génie logiciel par m.youssfiENSET, Université Hassan II Casablanca
 
Cours design pattern m youssfi partie 1 introduction et pattern strategy
Cours design pattern m youssfi partie 1 introduction et pattern strategyCours design pattern m youssfi partie 1 introduction et pattern strategy
Cours design pattern m youssfi partie 1 introduction et pattern strategyENSET, Université Hassan II Casablanca
 
softCours design pattern m youssfi partie 9 creation des objets abstract fact...
softCours design pattern m youssfi partie 9 creation des objets abstract fact...softCours design pattern m youssfi partie 9 creation des objets abstract fact...
softCours design pattern m youssfi partie 9 creation des objets abstract fact...ENSET, Université Hassan II Casablanca
 
Développement d'un site web jee de e commerce basé sur spring (m.youssfi)
Développement d'un site web jee de e commerce basé sur spring (m.youssfi)Développement d'un site web jee de e commerce basé sur spring (m.youssfi)
Développement d'un site web jee de e commerce basé sur spring (m.youssfi)ENSET, Université Hassan II Casablanca
 

En vedette (20)

Enib cours c.a.i. web - séance #5 : td grails
Enib   cours c.a.i. web - séance #5 : td grailsEnib   cours c.a.i. web - séance #5 : td grails
Enib cours c.a.i. web - séance #5 : td grails
 
ENIB cours CAI Web - Séance 4 - Frameworks/Spring - Cours
ENIB cours CAI Web - Séance 4 - Frameworks/Spring - CoursENIB cours CAI Web - Séance 4 - Frameworks/Spring - Cours
ENIB cours CAI Web - Séance 4 - Frameworks/Spring - Cours
 
Introduction au langage de script Groovy
Introduction au langage de script GroovyIntroduction au langage de script Groovy
Introduction au langage de script Groovy
 
L'approche par regles metier
L'approche par regles metierL'approche par regles metier
L'approche par regles metier
 
Introduction Groovy / Grails - Cyril Picat - December 2009
Introduction Groovy / Grails - Cyril Picat - December 2009Introduction Groovy / Grails - Cyril Picat - December 2009
Introduction Groovy / Grails - Cyril Picat - December 2009
 
Présentation Groovy
Présentation GroovyPrésentation Groovy
Présentation Groovy
 
Tests de performances d'une application Java EE
Tests de performances d'une application Java EETests de performances d'une application Java EE
Tests de performances d'une application Java EE
 
Drools et les moteurs de règles
Drools et les moteurs de règlesDrools et les moteurs de règles
Drools et les moteurs de règles
 
Cours design pattern m youssfi partie 6 proxy
Cours design pattern m youssfi partie 6 proxyCours design pattern m youssfi partie 6 proxy
Cours design pattern m youssfi partie 6 proxy
 
Cours design pattern m youssfi partie 3 decorateur
Cours design pattern m youssfi partie 3 decorateurCours design pattern m youssfi partie 3 decorateur
Cours design pattern m youssfi partie 3 decorateur
 
Cours design pattern m youssfi partie 4 composite
Cours design pattern m youssfi partie 4 compositeCours design pattern m youssfi partie 4 composite
Cours design pattern m youssfi partie 4 composite
 
Cours design pattern m youssfi partie 5 adapter
Cours design pattern m youssfi partie 5 adapterCours design pattern m youssfi partie 5 adapter
Cours design pattern m youssfi partie 5 adapter
 
Cours design pattern m youssfi partie 7 facade bridge flyweight
Cours design pattern m youssfi partie 7 facade bridge flyweightCours design pattern m youssfi partie 7 facade bridge flyweight
Cours design pattern m youssfi partie 7 facade bridge flyweight
 
Cours design pattern m youssfi partie 8 stat, template method, command , medi...
Cours design pattern m youssfi partie 8 stat, template method, command , medi...Cours design pattern m youssfi partie 8 stat, template method, command , medi...
Cours design pattern m youssfi partie 8 stat, template method, command , medi...
 
Java entreprise edition et industrialisation du génie logiciel par m.youssfi
Java entreprise edition et industrialisation du génie logiciel par m.youssfiJava entreprise edition et industrialisation du génie logiciel par m.youssfi
Java entreprise edition et industrialisation du génie logiciel par m.youssfi
 
Cours design pattern m youssfi partie 2 observer
Cours design pattern m youssfi partie 2 observerCours design pattern m youssfi partie 2 observer
Cours design pattern m youssfi partie 2 observer
 
Cours design pattern m youssfi partie 1 introduction et pattern strategy
Cours design pattern m youssfi partie 1 introduction et pattern strategyCours design pattern m youssfi partie 1 introduction et pattern strategy
Cours design pattern m youssfi partie 1 introduction et pattern strategy
 
softCours design pattern m youssfi partie 9 creation des objets abstract fact...
softCours design pattern m youssfi partie 9 creation des objets abstract fact...softCours design pattern m youssfi partie 9 creation des objets abstract fact...
softCours design pattern m youssfi partie 9 creation des objets abstract fact...
 
Support programmation orientée aspect mohamed youssfi (aop)
Support programmation orientée aspect mohamed youssfi (aop)Support programmation orientée aspect mohamed youssfi (aop)
Support programmation orientée aspect mohamed youssfi (aop)
 
Développement d'un site web jee de e commerce basé sur spring (m.youssfi)
Développement d'un site web jee de e commerce basé sur spring (m.youssfi)Développement d'un site web jee de e commerce basé sur spring (m.youssfi)
Développement d'un site web jee de e commerce basé sur spring (m.youssfi)
 

Similaire à BreizhCamp 2013 - Pimp my backend

Building Services With gRPC, Docker and Go
Building Services With gRPC, Docker and GoBuilding Services With gRPC, Docker and Go
Building Services With gRPC, Docker and GoMartin Kess
 
Apidays Paris 2023 - Forget TypeScript, Choose Rust to build Robust, Fast and...
Apidays Paris 2023 - Forget TypeScript, Choose Rust to build Robust, Fast and...Apidays Paris 2023 - Forget TypeScript, Choose Rust to build Robust, Fast and...
Apidays Paris 2023 - Forget TypeScript, Choose Rust to build Robust, Fast and...apidays
 
EuroPython 2013 - FAST, DOCUMENTED AND RELIABLE JSON BASED WEBSERVICES WITH P...
EuroPython 2013 - FAST, DOCUMENTED AND RELIABLE JSON BASED WEBSERVICES WITH P...EuroPython 2013 - FAST, DOCUMENTED AND RELIABLE JSON BASED WEBSERVICES WITH P...
EuroPython 2013 - FAST, DOCUMENTED AND RELIABLE JSON BASED WEBSERVICES WITH P...Alessandro Molina
 
Practical Use of MongoDB for Node.js
Practical Use of MongoDB for Node.jsPractical Use of MongoDB for Node.js
Practical Use of MongoDB for Node.jsasync_io
 
Building your first app with MongoDB
Building your first app with MongoDBBuilding your first app with MongoDB
Building your first app with MongoDBNorberto Leite
 
MongoDB at ZPUGDC
MongoDB at ZPUGDCMongoDB at ZPUGDC
MongoDB at ZPUGDCMike Dirolf
 
How Different are MongoDB Drivers
How Different are MongoDB DriversHow Different are MongoDB Drivers
How Different are MongoDB DriversNorberto Leite
 
Crystal internals (part 1)
Crystal internals (part 1)Crystal internals (part 1)
Crystal internals (part 1)Ary Borenszweig
 
Crystal internals (part 1)
Crystal internals (part 1)Crystal internals (part 1)
Crystal internals (part 1)Ary Borenszweig
 
Crystal internals (part 1)
Crystal internals (part 1)Crystal internals (part 1)
Crystal internals (part 1)Crystal Language
 
MongoTorino 2013 - BSON Mad Science for fun and profit
MongoTorino 2013 - BSON Mad Science for fun and profitMongoTorino 2013 - BSON Mad Science for fun and profit
MongoTorino 2013 - BSON Mad Science for fun and profitAlessandro Molina
 
Lessons Learned Migrating 2+ Billion Documents at Craigslist
Lessons Learned Migrating 2+ Billion Documents at CraigslistLessons Learned Migrating 2+ Billion Documents at Craigslist
Lessons Learned Migrating 2+ Billion Documents at CraigslistJeremy Zawodny
 
«Что такое serverless-архитектура и как с ней жить?» Николай Марков, Aligned ...
«Что такое serverless-архитектура и как с ней жить?» Николай Марков, Aligned ...«Что такое serverless-архитектура и как с ней жить?» Николай Марков, Aligned ...
«Что такое serverless-архитектура и как с ней жить?» Николай Марков, Aligned ...it-people
 
Social Analytics with MongoDB
Social Analytics with MongoDBSocial Analytics with MongoDB
Social Analytics with MongoDBPatrick Stokes
 
node.js, javascript and the future
node.js, javascript and the futurenode.js, javascript and the future
node.js, javascript and the futureJeff Miccolis
 
Intro to mobile web application development
Intro to mobile web application developmentIntro to mobile web application development
Intro to mobile web application developmentzonathen
 

Similaire à BreizhCamp 2013 - Pimp my backend (20)

Building Services With gRPC, Docker and Go
Building Services With gRPC, Docker and GoBuilding Services With gRPC, Docker and Go
Building Services With gRPC, Docker and Go
 
Kubernetes debug like a pro
Kubernetes debug like a proKubernetes debug like a pro
Kubernetes debug like a pro
 
Apidays Paris 2023 - Forget TypeScript, Choose Rust to build Robust, Fast and...
Apidays Paris 2023 - Forget TypeScript, Choose Rust to build Robust, Fast and...Apidays Paris 2023 - Forget TypeScript, Choose Rust to build Robust, Fast and...
Apidays Paris 2023 - Forget TypeScript, Choose Rust to build Robust, Fast and...
 
Introduction to python
Introduction to pythonIntroduction to python
Introduction to python
 
EuroPython 2013 - FAST, DOCUMENTED AND RELIABLE JSON BASED WEBSERVICES WITH P...
EuroPython 2013 - FAST, DOCUMENTED AND RELIABLE JSON BASED WEBSERVICES WITH P...EuroPython 2013 - FAST, DOCUMENTED AND RELIABLE JSON BASED WEBSERVICES WITH P...
EuroPython 2013 - FAST, DOCUMENTED AND RELIABLE JSON BASED WEBSERVICES WITH P...
 
Practical Use of MongoDB for Node.js
Practical Use of MongoDB for Node.jsPractical Use of MongoDB for Node.js
Practical Use of MongoDB for Node.js
 
Building your first app with MongoDB
Building your first app with MongoDBBuilding your first app with MongoDB
Building your first app with MongoDB
 
MongoDB at ZPUGDC
MongoDB at ZPUGDCMongoDB at ZPUGDC
MongoDB at ZPUGDC
 
How Different are MongoDB Drivers
How Different are MongoDB DriversHow Different are MongoDB Drivers
How Different are MongoDB Drivers
 
Crystal internals (part 1)
Crystal internals (part 1)Crystal internals (part 1)
Crystal internals (part 1)
 
Crystal internals (part 1)
Crystal internals (part 1)Crystal internals (part 1)
Crystal internals (part 1)
 
Crystal internals (part 1)
Crystal internals (part 1)Crystal internals (part 1)
Crystal internals (part 1)
 
MongoTorino 2013 - BSON Mad Science for fun and profit
MongoTorino 2013 - BSON Mad Science for fun and profitMongoTorino 2013 - BSON Mad Science for fun and profit
MongoTorino 2013 - BSON Mad Science for fun and profit
 
Lessons Learned Migrating 2+ Billion Documents at Craigslist
Lessons Learned Migrating 2+ Billion Documents at CraigslistLessons Learned Migrating 2+ Billion Documents at Craigslist
Lessons Learned Migrating 2+ Billion Documents at Craigslist
 
«Что такое serverless-архитектура и как с ней жить?» Николай Марков, Aligned ...
«Что такое serverless-архитектура и как с ней жить?» Николай Марков, Aligned ...«Что такое serverless-архитектура и как с ней жить?» Николай Марков, Aligned ...
«Что такое serverless-архитектура и как с ней жить?» Николай Марков, Aligned ...
 
Introduce Django
Introduce DjangoIntroduce Django
Introduce Django
 
Social Analytics with MongoDB
Social Analytics with MongoDBSocial Analytics with MongoDB
Social Analytics with MongoDB
 
node.js, javascript and the future
node.js, javascript and the futurenode.js, javascript and the future
node.js, javascript and the future
 
Intro to mobile web application development
Intro to mobile web application developmentIntro to mobile web application development
Intro to mobile web application development
 
Revealing ALLSTOCKER
Revealing ALLSTOCKERRevealing ALLSTOCKER
Revealing ALLSTOCKER
 

Plus de Horacio Gonzalez

Il n'y a pas que Polymer dans la vie… - RennesJS - 2017-06-27
Il n'y a pas que Polymer dans la vie… - RennesJS - 2017-06-27Il n'y a pas que Polymer dans la vie… - RennesJS - 2017-06-27
Il n'y a pas que Polymer dans la vie… - RennesJS - 2017-06-27Horacio Gonzalez
 
But there is no web component for that - Web Components Remote Conference - 2...
But there is no web component for that - Web Components Remote Conference - 2...But there is no web component for that - Web Components Remote Conference - 2...
But there is no web component for that - Web Components Remote Conference - 2...Horacio Gonzalez
 
Mixité dans le monde des WebComponents - DevFest Toulouse - 2017-09-27
 Mixité dans le monde des WebComponents - DevFest Toulouse - 2017-09-27 Mixité dans le monde des WebComponents - DevFest Toulouse - 2017-09-27
Mixité dans le monde des WebComponents - DevFest Toulouse - 2017-09-27Horacio Gonzalez
 
ENIB 2016 2017 - CAI Web S02E01- Côté navigateur 2/3 - HTML5, CSS3, Twitter B...
ENIB 2016 2017 - CAI Web S02E01- Côté navigateur 2/3 - HTML5, CSS3, Twitter B...ENIB 2016 2017 - CAI Web S02E01- Côté navigateur 2/3 - HTML5, CSS3, Twitter B...
ENIB 2016 2017 - CAI Web S02E01- Côté navigateur 2/3 - HTML5, CSS3, Twitter B...Horacio Gonzalez
 
ENIB 2016 2017 - CAI Web S02E01- Côté navigateur 1/3 - HTTP, HTML, CSS, JS
ENIB 2016 2017 - CAI Web S02E01- Côté navigateur 1/3 - HTTP, HTML, CSS, JSENIB 2016 2017 - CAI Web S02E01- Côté navigateur 1/3 - HTTP, HTML, CSS, JS
ENIB 2016 2017 - CAI Web S02E01- Côté navigateur 1/3 - HTTP, HTML, CSS, JSHoracio Gonzalez
 
Battle of Frameworks: Polymer - Meetup Paris Web Components - 2016-09
Battle of Frameworks: Polymer - Meetup Paris Web Components - 2016-09Battle of Frameworks: Polymer - Meetup Paris Web Components - 2016-09
Battle of Frameworks: Polymer - Meetup Paris Web Components - 2016-09Horacio Gonzalez
 
Mixing Web Components - Best of Web Paris - 2016 06-09
Mixing Web Components - Best of Web Paris - 2016 06-09Mixing Web Components - Best of Web Paris - 2016 06-09
Mixing Web Components - Best of Web Paris - 2016 06-09Horacio Gonzalez
 
Polymer in the real life - Devoxx France - 2016 04-20
Polymer in the real life - Devoxx France - 2016 04-20Polymer in the real life - Devoxx France - 2016 04-20
Polymer in the real life - Devoxx France - 2016 04-20Horacio Gonzalez
 
Warp10: collect, store and manipulate sensor data - BreizhCamp - 2016 03-24
Warp10: collect, store and manipulate sensor data - BreizhCamp - 2016 03-24 Warp10: collect, store and manipulate sensor data - BreizhCamp - 2016 03-24
Warp10: collect, store and manipulate sensor data - BreizhCamp - 2016 03-24 Horacio Gonzalez
 
ENIB 2015 2016 - CAI Web S02E03- Forge JS 1/4 - La forge JavaScript
ENIB 2015 2016 - CAI Web S02E03- Forge JS 1/4 - La forge JavaScriptENIB 2015 2016 - CAI Web S02E03- Forge JS 1/4 - La forge JavaScript
ENIB 2015 2016 - CAI Web S02E03- Forge JS 1/4 - La forge JavaScriptHoracio Gonzalez
 
ENIB 2015 2016 - CAI Web S02E01- Côté Navigateur 3/3 - Web Components avec Po...
ENIB 2015 2016 - CAI Web S02E01- Côté Navigateur 3/3 - Web Components avec Po...ENIB 2015 2016 - CAI Web S02E01- Côté Navigateur 3/3 - Web Components avec Po...
ENIB 2015 2016 - CAI Web S02E01- Côté Navigateur 3/3 - Web Components avec Po...Horacio Gonzalez
 
ENIB 2015 2016 - CAI Web S02E03 - Forge JS 2/4 - MongoDB and NoSQL
ENIB 2015 2016 - CAI Web S02E03 - Forge JS 2/4 - MongoDB and NoSQLENIB 2015 2016 - CAI Web S02E03 - Forge JS 2/4 - MongoDB and NoSQL
ENIB 2015 2016 - CAI Web S02E03 - Forge JS 2/4 - MongoDB and NoSQLHoracio Gonzalez
 
ENIB 2015 2016 - CAI Web S02E01- Côté Navigateur 1/3 - HTTP, HTML, CSS JS
ENIB 2015 2016 - CAI Web S02E01- Côté Navigateur 1/3 - HTTP, HTML, CSS JSENIB 2015 2016 - CAI Web S02E01- Côté Navigateur 1/3 - HTTP, HTML, CSS JS
ENIB 2015 2016 - CAI Web S02E01- Côté Navigateur 1/3 - HTTP, HTML, CSS JSHoracio Gonzalez
 
ENIB 2015-2016 - CAI Web - S01E01- MongoDB and NoSQL
ENIB 2015-2016 - CAI Web - S01E01- MongoDB and NoSQLENIB 2015-2016 - CAI Web - S01E01- MongoDB and NoSQL
ENIB 2015-2016 - CAI Web - S01E01- MongoDB and NoSQLHoracio Gonzalez
 
ENIB 2015-2016 - CAI Web - S01E01- La forge JavaScript
ENIB 2015-2016 - CAI Web - S01E01- La forge JavaScriptENIB 2015-2016 - CAI Web - S01E01- La forge JavaScript
ENIB 2015-2016 - CAI Web - S01E01- La forge JavaScriptHoracio Gonzalez
 
ENIB 2015-2016 - CAI Web - S01E01- Côté navigateur 2/3 - HTML5, CSS3, Twitte...
ENIB 2015-2016 - CAI Web -  S01E01- Côté navigateur 2/3 - HTML5, CSS3, Twitte...ENIB 2015-2016 - CAI Web -  S01E01- Côté navigateur 2/3 - HTML5, CSS3, Twitte...
ENIB 2015-2016 - CAI Web - S01E01- Côté navigateur 2/3 - HTML5, CSS3, Twitte...Horacio Gonzalez
 
ENIB 2015-2016 - CAI Web - S01E01- Côté navigateur 1/3 - HTTP, HTML, CSS, JS
ENIB 2015-2016 - CAI Web -  S01E01- Côté navigateur 1/3 - HTTP, HTML, CSS, JSENIB 2015-2016 - CAI Web -  S01E01- Côté navigateur 1/3 - HTTP, HTML, CSS, JS
ENIB 2015-2016 - CAI Web - S01E01- Côté navigateur 1/3 - HTTP, HTML, CSS, JSHoracio Gonzalez
 
ENIB 2015-2016 - CAI Web - S01E01- Côté navigateur 3/3 - Web components avec ...
ENIB 2015-2016 - CAI Web - S01E01- Côté navigateur 3/3 - Web components avec ...ENIB 2015-2016 - CAI Web - S01E01- Côté navigateur 3/3 - Web components avec ...
ENIB 2015-2016 - CAI Web - S01E01- Côté navigateur 3/3 - Web components avec ...Horacio Gonzalez
 
Beyond Polymer - JUG Summer Camp - 2015-09-18
Beyond Polymer - JUG Summer Camp - 2015-09-18Beyond Polymer - JUG Summer Camp - 2015-09-18
Beyond Polymer - JUG Summer Camp - 2015-09-18Horacio Gonzalez
 
Mixing Web Components - Paris Web Components - 2015 09-16
Mixing Web Components - Paris Web Components - 2015 09-16 Mixing Web Components - Paris Web Components - 2015 09-16
Mixing Web Components - Paris Web Components - 2015 09-16 Horacio Gonzalez
 

Plus de Horacio Gonzalez (20)

Il n'y a pas que Polymer dans la vie… - RennesJS - 2017-06-27
Il n'y a pas que Polymer dans la vie… - RennesJS - 2017-06-27Il n'y a pas que Polymer dans la vie… - RennesJS - 2017-06-27
Il n'y a pas que Polymer dans la vie… - RennesJS - 2017-06-27
 
But there is no web component for that - Web Components Remote Conference - 2...
But there is no web component for that - Web Components Remote Conference - 2...But there is no web component for that - Web Components Remote Conference - 2...
But there is no web component for that - Web Components Remote Conference - 2...
 
Mixité dans le monde des WebComponents - DevFest Toulouse - 2017-09-27
 Mixité dans le monde des WebComponents - DevFest Toulouse - 2017-09-27 Mixité dans le monde des WebComponents - DevFest Toulouse - 2017-09-27
Mixité dans le monde des WebComponents - DevFest Toulouse - 2017-09-27
 
ENIB 2016 2017 - CAI Web S02E01- Côté navigateur 2/3 - HTML5, CSS3, Twitter B...
ENIB 2016 2017 - CAI Web S02E01- Côté navigateur 2/3 - HTML5, CSS3, Twitter B...ENIB 2016 2017 - CAI Web S02E01- Côté navigateur 2/3 - HTML5, CSS3, Twitter B...
ENIB 2016 2017 - CAI Web S02E01- Côté navigateur 2/3 - HTML5, CSS3, Twitter B...
 
ENIB 2016 2017 - CAI Web S02E01- Côté navigateur 1/3 - HTTP, HTML, CSS, JS
ENIB 2016 2017 - CAI Web S02E01- Côté navigateur 1/3 - HTTP, HTML, CSS, JSENIB 2016 2017 - CAI Web S02E01- Côté navigateur 1/3 - HTTP, HTML, CSS, JS
ENIB 2016 2017 - CAI Web S02E01- Côté navigateur 1/3 - HTTP, HTML, CSS, JS
 
Battle of Frameworks: Polymer - Meetup Paris Web Components - 2016-09
Battle of Frameworks: Polymer - Meetup Paris Web Components - 2016-09Battle of Frameworks: Polymer - Meetup Paris Web Components - 2016-09
Battle of Frameworks: Polymer - Meetup Paris Web Components - 2016-09
 
Mixing Web Components - Best of Web Paris - 2016 06-09
Mixing Web Components - Best of Web Paris - 2016 06-09Mixing Web Components - Best of Web Paris - 2016 06-09
Mixing Web Components - Best of Web Paris - 2016 06-09
 
Polymer in the real life - Devoxx France - 2016 04-20
Polymer in the real life - Devoxx France - 2016 04-20Polymer in the real life - Devoxx France - 2016 04-20
Polymer in the real life - Devoxx France - 2016 04-20
 
Warp10: collect, store and manipulate sensor data - BreizhCamp - 2016 03-24
Warp10: collect, store and manipulate sensor data - BreizhCamp - 2016 03-24 Warp10: collect, store and manipulate sensor data - BreizhCamp - 2016 03-24
Warp10: collect, store and manipulate sensor data - BreizhCamp - 2016 03-24
 
ENIB 2015 2016 - CAI Web S02E03- Forge JS 1/4 - La forge JavaScript
ENIB 2015 2016 - CAI Web S02E03- Forge JS 1/4 - La forge JavaScriptENIB 2015 2016 - CAI Web S02E03- Forge JS 1/4 - La forge JavaScript
ENIB 2015 2016 - CAI Web S02E03- Forge JS 1/4 - La forge JavaScript
 
ENIB 2015 2016 - CAI Web S02E01- Côté Navigateur 3/3 - Web Components avec Po...
ENIB 2015 2016 - CAI Web S02E01- Côté Navigateur 3/3 - Web Components avec Po...ENIB 2015 2016 - CAI Web S02E01- Côté Navigateur 3/3 - Web Components avec Po...
ENIB 2015 2016 - CAI Web S02E01- Côté Navigateur 3/3 - Web Components avec Po...
 
ENIB 2015 2016 - CAI Web S02E03 - Forge JS 2/4 - MongoDB and NoSQL
ENIB 2015 2016 - CAI Web S02E03 - Forge JS 2/4 - MongoDB and NoSQLENIB 2015 2016 - CAI Web S02E03 - Forge JS 2/4 - MongoDB and NoSQL
ENIB 2015 2016 - CAI Web S02E03 - Forge JS 2/4 - MongoDB and NoSQL
 
ENIB 2015 2016 - CAI Web S02E01- Côté Navigateur 1/3 - HTTP, HTML, CSS JS
ENIB 2015 2016 - CAI Web S02E01- Côté Navigateur 1/3 - HTTP, HTML, CSS JSENIB 2015 2016 - CAI Web S02E01- Côté Navigateur 1/3 - HTTP, HTML, CSS JS
ENIB 2015 2016 - CAI Web S02E01- Côté Navigateur 1/3 - HTTP, HTML, CSS JS
 
ENIB 2015-2016 - CAI Web - S01E01- MongoDB and NoSQL
ENIB 2015-2016 - CAI Web - S01E01- MongoDB and NoSQLENIB 2015-2016 - CAI Web - S01E01- MongoDB and NoSQL
ENIB 2015-2016 - CAI Web - S01E01- MongoDB and NoSQL
 
ENIB 2015-2016 - CAI Web - S01E01- La forge JavaScript
ENIB 2015-2016 - CAI Web - S01E01- La forge JavaScriptENIB 2015-2016 - CAI Web - S01E01- La forge JavaScript
ENIB 2015-2016 - CAI Web - S01E01- La forge JavaScript
 
ENIB 2015-2016 - CAI Web - S01E01- Côté navigateur 2/3 - HTML5, CSS3, Twitte...
ENIB 2015-2016 - CAI Web -  S01E01- Côté navigateur 2/3 - HTML5, CSS3, Twitte...ENIB 2015-2016 - CAI Web -  S01E01- Côté navigateur 2/3 - HTML5, CSS3, Twitte...
ENIB 2015-2016 - CAI Web - S01E01- Côté navigateur 2/3 - HTML5, CSS3, Twitte...
 
ENIB 2015-2016 - CAI Web - S01E01- Côté navigateur 1/3 - HTTP, HTML, CSS, JS
ENIB 2015-2016 - CAI Web -  S01E01- Côté navigateur 1/3 - HTTP, HTML, CSS, JSENIB 2015-2016 - CAI Web -  S01E01- Côté navigateur 1/3 - HTTP, HTML, CSS, JS
ENIB 2015-2016 - CAI Web - S01E01- Côté navigateur 1/3 - HTTP, HTML, CSS, JS
 
ENIB 2015-2016 - CAI Web - S01E01- Côté navigateur 3/3 - Web components avec ...
ENIB 2015-2016 - CAI Web - S01E01- Côté navigateur 3/3 - Web components avec ...ENIB 2015-2016 - CAI Web - S01E01- Côté navigateur 3/3 - Web components avec ...
ENIB 2015-2016 - CAI Web - S01E01- Côté navigateur 3/3 - Web components avec ...
 
Beyond Polymer - JUG Summer Camp - 2015-09-18
Beyond Polymer - JUG Summer Camp - 2015-09-18Beyond Polymer - JUG Summer Camp - 2015-09-18
Beyond Polymer - JUG Summer Camp - 2015-09-18
 
Mixing Web Components - Paris Web Components - 2015 09-16
Mixing Web Components - Paris Web Components - 2015 09-16 Mixing Web Components - Paris Web Components - 2015 09-16
Mixing Web Components - Paris Web Components - 2015 09-16
 

Dernier

TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesKari Kakkonen
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...Wes McKinney
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...panagenda
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesThousandEyes
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfpanagenda
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 

Dernier (20)

TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examples
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 

BreizhCamp 2013 - Pimp my backend

  • 1. By @FinistSeb and @LostInBrittany
  • 2. Sebastien Lambour Le développeur de l'Est le plus à l'Ouest ! Java & C++ Developer, coding addict, continuous intégration ayatollah ● Senior Software Engineer currently, Crédit Mutuel Arkea ● FinistJug actif member BreizhBeans community and commiter sebastien.lambour@gmail.com +sebastien.lambour @FinistSeb
  • 3. Horacio Gonzalez Spaniard lost in Brittany, Java developer, dreamer and all-around geek ● Senior Software Engineer at Crédit Mutuel Arkea ○ Currently... ● Leader of the FinistJUG and the BreizhBeans community http://lostinbrittany.org/ +Horacio.Gonzalez @LostInBrittany
  • 4. BreizhBeans Developer community at the far end of French Brittany http://breizhbeans.org/ @BreizhBeans
  • 5. Why ? I help to create a startup on social translation, would you code with me ? Great, I do the backend! How many members? Some 30.000 - 50.000 will be fine! Ouch, is it not too small? I like big toys!!!! Nexus 4 Me too! Let's think big then OK, it will rock !
  • 7. Transforming it is HARD ! Next challenge : Granite aircraft !!
  • 8. A sexy backend? Let's groom it! Light weight Data Driven Java Cloud Ready OK, go around... Test driven Scalable
  • 9. Following the beaten track Brainless route JSF 2.0 Hibernate Spring CRUD (Create, Read, Update,Delete) SQL JPA CXF The usual suspects...
  • 11. Design choices Because we need some solid roots
  • 12. Core principles What do we want our backend to be? ● Scalability ○ ● Adaptability ○ ● Because you want to be sure that your code works! NoSQL (meaning Not Only SQL) ○ ● Because your business evolves, and your backend need to evolve with it! Testability ○ ● Because traffic growth should be a blessing, not a problem! Because you need not only tables and foreign keys, but non-SQL stores, search indexes, caches... Productivity ○ Because the other 4 doesn't matter if you need to spend 4 working days to modify a service...
  • 13. A first choice : Apache Thrift « Software framework for scalable and performant crosslanguage services development » ● ● ● ● ● Interface description language Multi-language code generation Serialisation/deserialisation RPC Framework High performance ○ On transport layer ○ On data manipulation
  • 14. Thrift, it's cool Thrift boots productivity!
  • 15. A second choice : MongoDB ● We needed a NO-SQL store for documents ● We wanted to use Cassandra ○ Cassandra & Thrift, a love story ● We wanted a PaaS-ready backend ○ Neither Cloudbees nor Cloudfoundry supported Cassandra ○ But they supported MongoDB ● We loved MongoDB ○ Document DB are great for document oriented applications
  • 16. ThriftMongoBridge Because we wanted both Thrift and MongoDB
  • 17. Thrift rocks and works But... How to put Thrift objects into MongoDB ?
  • 18. First bad idea! Use Spring Data or Morphia Thrift object mapping is bad !
  • 20. Second bad idea ! Use the Mongo Driver JSON parsing Deserialisation will be a bit hard...
  • 22. Thrift isn't cool anymore ? We need a new idea !
  • 23. Thrift, it's cool ! But we had work to do... Write a TBSONProtocol ! The ThriftMongoBridge is born !
  • 24. What does it do ? POJO generated by the Thrift compiler public class AnotherThrift implements org.apache.thrift.TBase... { ... public String anotherString; public int anotherInteger; Thrift IDL struct AnotherThrift { 1:string anotherString, 2:i32 anotherInteger, } Compile to ... public static final Map<_Fields, org.apache.thrift.meta_data. FieldMetaData> metaDataMap; .... public void read(org.apache.thrift.protocol.TProtocol iprot)... ... public void write(org.apache.thrift.protocol.TProtocol oprot) ......; } TBSonSerializer TBSonProtocol Write To BSON TBSonDeSerializer Read from BSON {anotherString:"value", anotherInteger:69}
  • 25. Really simple to use Too simple ? AnotherThrift anotherThrift = new AnotherThrift(); anotherThrift.setAnotherString("value"); anotherThrift.setAnotherInteger(69); // serialize into DBObject DBObject dbObject = ThriftMongoHelper.thrift2DBObject(anotherThrift); {anotherString:"value", anotherInteger:69}
  • 26. How it works write(protocol) Thrift object generated TBSONSerializer TBase getResult sentense directives (begin / end) push Data (read / write) pop Struct context DBObject Context Stack TBSONProtocol DBObject (BSON) MongoDB object
  • 27. The BreizhCamp demo Because you want to see some code, don't you?
  • 28. The BreizhCamp demo Given this Thrift model & service struct BreizhCampEvent { 1:i64 date, 2:string startTime, 3:string endTime, 4:com.breizhbeans.backend.thrift.enums.model.EventTypes type, 5:string room, 6:string resume, 7:string details, 8:list<string> speakers 9:list<com.breizhbeans.backend.thrift.enums.model.Track> tracks, } service ProgramService { com.....GetProgramResponse getProgram(1:com.....GetProgramRequest request) throws (1:com....TechnicalException texp, 2:com...FunctionalException fexp) } struct GetProgramRequest { 1:com.breizhbeans.backend.thrift.enums.model.Track track, 2:com.breizhbeans.backend.thrift.enums.model.EventTypes type, 3:string room, 4:list<string> speakers, } struct GetProgramResponse { 1:list<com.breizhbeans.backend.thrift.model.BreizhCampEvent> events, }
  • 29. The BreizhCamp demo First : Write a test ● One loader by collection ● One goal : Have Human readable test ;-) ● Manage automatically data insertion before test and clean up after test Application code to test @Test public void testGetEvents() throws Exception { List<BreizhCampEvent> actualEvents = programDao.getEvent(); List<BreizhCampEvent> expectedEvents = new ArrayList<BreizhCampEvent>(); expectedEvents.add(getEventPimpMyBackend()); Assert.assertEquals(expectedEvents, actualEvents); } Expected data building (used by the test and the data loader) Standard JUnit assertion
  • 30. The BreizhCamp demo Write a DAO public List<BreizhCampEvent> getEvent() throws TechnicalException { DBCursor cursor = null; try { List<BreizhCampEvent> events = new ArrayList<BreizhCampEvent>(); DBCollection collection = db.getCollection(collectionName); DBObject query = new BasicDBObject(); // execute the query retrieve DB collection cursor = collection.find(query); while(cursor.hasNext()) { Build and execute the Query events.add( (BreizhCampEvent) ThriftMongoHelper.DBObject2Thrift(cursor.next())); } return events; } catch (Exception e) { throw new H4TTechnicalException("Unexpected error", e, null); Deserialize Thrift objects } finally { cursor.close(); } Error handling } Never forget it ;-)
  • 31. The BreizhCamp demo Can I update thrift Object by code? @Override public BreizhCampEvent updateRoom(final BreizhCampEvent event) throws TechnicalException { try { BasicDBObject updateQuery = new BasicDBObject(); Mongo Update Query updateQuery.append("$set", new BasicDBObject() .append(getFields(BreizhCampEvent._Fields.ROOM), event.getRoom())); db.getCollection(collectionName) .update(getPrimaryKeyRequest(event), updateQuery) .getLastError() Thrift structure mapping .throwOnError(); return event; } catch (Exception e) { Query execution throw new H4TTechnicalException("Unexpected error", e, ObjectUtils.toString(event)); } } Error handling
  • 32. The BreizhCamp demo Can I update thrift Object by script? Mongo DB Bson writed : > db.program.find(); { "_id" : "id=10", "date" : NumberLong("-56433978000000"), "startTime" : "14:45", "endTime" : "15:40", "type" : 4, "room" : "Bréhat", "resume" : "Pimp my backend!", "details" : "Le frontend, le frontend...... ...", "speakers" : [ "Sébastien Lambour", "Horacio Gonzalez" ], "tracks" : [ 7 ], "id" : 10, "classname" : "com.breizhbeans.backend.thrift.model. BreizhCampEvent" } Update the field room :> db.program.update(); { "id": 10}, { $set: { "room": "Ouessant" } }
  • 33. And the perfs? Because speed matters!
  • 34. Talking about perfs The candidates are ... Spring Data Morphia And... ThriftMongoBridge, of course
  • 35. Spring Data vs ThriftMongoBridge ● Write and Read 500 objects into MongoDB. ● Each document is composed with a List<> and a Set<> of 500 objects. ● The document have a JSON size of 91613 bytes Who will win ?
  • 36. Code ThriftMongoBridge First // Get a collection DBCollection collection = db.getCollection("dummyColl"); Write // Serialize the Thrift object DBObject dbObject = ThriftMongoHelper.thrift2DBObject(thriftObject); // Put the document collection.insert(dbObject); Read DBCursor cursorDoc = collection.find(); while (cursorDoc.hasNext()) { DBObject dbObject = cursorDoc.next(); ThriftObject thirftObject = (ThriftObject)ThriftMongoHelper.DBObject2Thrift(dbObject); }
  • 37. Code Spring Data First // Retrieve the MongoOperations bean MongoOperations mongoOperation = (MongoOperations) ctx.getBean("mongoTemplate"); Write // Serialize the Thrift object mongoOperation.save(springObject, "springObject"); Read List<SpringObject> listUser = mongoOperation.findAll(SpringObject.class, "springObject");
  • 39. Thrift over MongoDB rocks! We need a logo for our OpenSource library... Available now : 2.0 https://github.com/BreizhBeans/ThriftTools
  • 40. A storage library a backend is not, young padawan Because we need more things
  • 41. At the beginning... Pretty layers, neatly isolated, like a Care Bears' birthday cake
  • 42. Later in the project Like a cake after an earthquake
  • 43. And in the end... As pretty as a British pudding... and almost as tasty
  • 44. Be Layer less Now build the Backend ! le b ha c rea un ● Each package have a goal ● NO package assembly rules ● Improve the complexity detection by dependencies analysis Goal : Fight against the "God classes" anti-pattern m ea dr
  • 45. Thrift services Prevent protocol rupture, have a stable services signature. com.h4t.CheckAccessResponse checkAccess (1:com.h4t.CheckAccessRequest request) throws (1:com.h4t.TechnicalException texp, 2:com.h4t.FunctionalException fexp) stable method signature
  • 46. Integrate this into the backend Thrift IFace implementation Request / Response decapsulation + log & monitoring Core Business code Thrift object read write ThriftMongoHelper Mongo Opérations Query DBObject DBObject Mongo Driver
  • 47. Inversion of control Keep simple too ! Prefer static dependencies injection. Time to do the choice or
  • 48. Inversion of control Why Because ? and ○ binding of the MongoDB service by the cloud ○ no production configuration required ○ only one war
  • 50. Test strategy No compromise! The rules are simple... no exception!
  • 51. TDD is my religion 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. Execute test without setup Execute test with your build tool Execute test into your IDE No injection into test framework Reuse only application injection Keep it simple (repeat it 7 times) Have a loose coupling (test the smallest parts) Test must be deterministic and reproducible Do pair review with the tests If the complexity is growing up refactor now ... 11. If a rule goes wrong, rewrite it !
  • 52. From concept to reality Load thrift object with preset datas into MongoDB Get expected Thift object with preset datas Collection Loader Thrift DataSet ThriftMongoTestTools Get a Thrift object from MongoDB related to a unique key
  • 53. Tests have goals DAO : Validate queries and set up the test data loaders IFACE : Functional tests SERVICE : Test a business centric service TU : Unit test not related to the business (test first approach)
  • 54. Tests are Data Driven @Before public void setUp() throws Exception { Inject Data into MongoDB eventLoader.load(getEventPimpMyBackend()); } private BreizhCampEvent getEventPimpMyBackend() throws Exception { String details = "Le frontend, le frontend... ....."; BreizhCampEvent event = eventLoader.getExpected(10, "14/06/2013", "14:45", "15: 40", EventTypes.CONF, "Bréhat", "Pimp my backend!", details); event = eventLoader.addSpeakers(event, "Sébastien Lambour", "Horacio Gonzalez"); event = eventLoader.addTracks(event, Track.CLOUD); return event; } Build test Data with java code, files, BDD or the MongoThrift Test tools (not opensourced yet ;-) )
  • 55. What's next? Because our work is not completed... yet!
  • 56. Why integrate our lib ? #Pragmatism ● ● ● ● Productivity oriented Fully testable Container less (no servlet dependencies) Open Source : Apache 2.0 The ThriftMongoBackend Core model will born soon ! With a name: TINAF (ThriftMongoBackend Is Not A Framework)
  • 57. What's next ? ● monitoring Thrift services in the cloud ● load tests with vmware & 10gen ● contribute TINAF ● Develop a thrift service valve to ensure brandwitdth for critical services