Slide 1

Slide 1 text

THE ART OF #FRAMEWORKLESS IN THE BACKEND Matteo Vaccari @xpmatteo

Slide 2

Slide 2 text

You have a choice, in your growth as a developer

Slide 3

Slide 3 text

You may look for a simplified, maybe more pleasant way to deal with reality

Slide 4

Slide 4 text

And look for a framework that will provide that simplified worldview for you. What is your growth path then?

Slide 5

Slide 5 text

You can become a developer that knows his framework(s) very well. Your growth is in learning more frameworks and learn them better. You will have plenty to learn! And I don’t say this is necessarily bad. However…

Slide 6

Slide 6 text

There is another way: you may want to deal with reality as it is. To go closer to the metal.

Slide 7

Slide 7 text

To do this, you will need knowledge of a more fundamental nature. There is a world of things to learn! This kind of knowledge is more enduring, more versatile, more powerful.

Slide 8

Slide 8 text

… and you may gain superpowers :-)

Slide 9

Slide 9 text

Frameworks? Risk Functionality Performance Obsolescence Incompatibilities Developer Experience App startup time Test running time The bad The good Learning Standardisation Bad habits DB-Centric Quick project startup Extra work Upgrades Searching on Stackoverflow for answers Addiction Anything is good or bad in a particular context, for a particular set of goals.

Slide 10

Slide 10 text

I prepared a small demo of an API that plays the game of hangman. I wrote three versions of it; the first uses Spring and JPA. The second replaces JPA with plain JDBC calls. The third one removes Spring and uses the Servlet API.

Slide 11

Slide 11 text

Creating a new game All three versions respond in the same way. This is a sample of how to play.

Slide 12

Slide 12 text

First guess: the letter “e”

Slide 13

Slide 13 text

Second guess: the letter “t”

Slide 14

Slide 14 text

Etc, etc…

Slide 15

Slide 15 text

A small demo of how it feels to start a Spring/JPA service versus a plain Java one.

Slide 16

Slide 16 text

Spring/JPA (Spring MVC) Controller Embedded Tomcat Spring MVC Servlet (Spring) Application Service (JPA) Repository Emtity Manager DB Our router Embedded Jetty Our Servlet Our Application Service Our Repository JDBC DB Domain Objects Domain Objects Domain Objects Domain Objects Domain Objects Domain Objects Domain Objects Domain Objects

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

No content

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

No content

Slide 22

Slide 22 text

Spring/JPA No Spring/No JPA (Spring MVC) Controller Embedded Tomcat Spring MVC Servlet (Spring) Application Service (JPA) Repository Emtity Manager DB Our router Embedded Jetty Our Servlet Our Application Service Our Repository JDBC DB Domain Objects Domain Objects Domain Objects Domain Objects Domain Objects Domain Objects Domain Objects Domain Objects

Slide 23

Slide 23 text

HttpServletRequest HttpServletResponse A Java web application is (not exactly, but similar to) a function that transforms an HttpServletRequest into an HttpServletResponse.

Slide 24

Slide 24 text

HttpServletRequest HttpServletResponse WebRequest WebResponse However, those servlet API objects have 50+ methods and are very low level and hard to use. One key thing to make #frameworkless work well is to write simple code. Therefore, it’s good to transform the servlet API objects into something simpler and easier to use. These are custom made for each project, similar but never exactly the same thing.

Slide 25

Slide 25 text

HttpServletRequest HttpServletResponse WebRequest WebResponse GameResponse x HttpStatus GuessRequest And this is still not enough; for any particular request, we probably want to transform the WebRequest into a specific request object that contains exactly what we need.

Slide 26

Slide 26 text

Main

Slide 27

Slide 27 text

The “Main Partition”

Slide 28

Slide 28 text

The “Main Partition” The main and the servlet together are what Uncle Bob calls the “main partition”, that is, the place where objects are constructed. The main (of course) is executed once per process, while the servlet service method is executed once per request. It is a sort of “main” for the request.

Slide 29

Slide 29 text

The Router

Slide 30

Slide 30 text

The Router The router’s job is to decide what is the user trying to do, and dispatch to an appropriate service call. The code of the router is made much simpler by having some logic in the WebRequest and WebResponse.

Slide 31

Slide 31 text

The Router, part II

Slide 32

Slide 32 text

The Router, part IIFor a simple service, a chain of IFs is simple and effective. If the service grows, it will probably evolve towards a table lookup. Again, this object should be developed afresh for every project/service. There’s no need to create a reusable “custom framework” here.

Slide 33

Slide 33 text

The Application Service

Slide 34

Slide 34 text

The Application Service The application service job is (a) to invoke business logic on domain objects, and (b) to deal with non-functional effects such as persistence.

Slide 35

Slide 35 text

The Domain Objects

Slide 36

Slide 36 text

The Game Repository

Slide 37

Slide 37 text

The Game Repository The GuessRequest contains data that are not used by the business logic, but are relevant for audit/security/debug purposes. This information is saved in a way that does not pollute the business logic (compare the GuessRequest, shown later, with the Guess domain object) The QueryRunner is from Apache Dblib. It’s possible to write your own; it’s no more than 10 lines of code.

Slide 38

Slide 38 text

The Game Repository, part II

Slide 39

Slide 39 text

The Game Repository, part II Reconstructing a Game involves replaying all the “guesses” of the player. This not exactly event sourcing, but it’s similar. I find that saving all the “events” involving an aggregate, with as little processing as possible at write time, makes persistence simpler, even when you don’t go full event- sourcing. Perhaps this way can be even better than full event-sourcing :-)

Slide 40

Slide 40 text

The Web Request

Slide 41

Slide 41 text

The Web Request The API of the WebRequest is at the same time simpler and higher level than the servlet API. The getOptionalParameter() and getMandatoryParameter() methods simplify the router and the service.

Slide 42

Slide 42 text

The Guess Request

Slide 43

Slide 43 text

Spring/JPA Spring/— —/— Server startup time ~6s ~3s 0.4s Time to run all tests 10s 5.5s 3.5s Time to run slowest test 7s 4-5s 1s # of tests 25 24 48 SLOC prod 360 424 643 SLOC test 358 357 745 jar size 30MB 17MB 6.3MB Judge for yourself.

Slide 44

Slide 44 text

Frameworks? Risk Functionality Performance Obsolescence Incompatibilities Developer Experience App startup time Test running time The bad The good Learning Standardisation Bad habits DB-Centric Quick project startup Extra work Upgrades Searching on Stackoverflow for answers Addiction

Slide 45

Slide 45 text

References https://github.com/xpmatteo/frameworkless-hangman https://github.com/frameworkless-movement/manifesto 45

Slide 46

Slide 46 text

twitter.com/xpmatteo thoughtworks.com THANK YOU WE ARE HIRING! YES, IN ITALY!