Last week I have attended JavaLand 2019 which was a great experience for me. Lots of different people, interesting talks and great speakers! It was my first time there and I have to admit: not only the usual conference content was great, but also the location was really unique – it’s located in Phantasia Land, an amusement park in Cologne, Germany.
I gained a lot of new ideas and thoughts which I want to share with you here. This is not a super-detailed summary of each talk, so don’t expect a complete lecture. Instead, I want to give you an idea of some talks, so you can dig deeper if you think it’s interesting for you. The reason is quite simple: Doing something on your own will bring the best learning experience.
My Lessons Learned (or: TL;DR)
Based on the talk program and content, you can see a rough direction where the Java world is heading to and what’s currently going on there. Most of the talks I’ve visited have been around the following two topics:
- Microservices, Microservices, Microservices: You should know what microservices are and how you can use them. Especially transactions in microservices are tricky, hence there were actually two talks about this topic. A common suggestion was to read the book “Microservices Patterns“.
- Domain Driven Design (DDD): If you don’t know what it is, you should have a look at a few articles online or read the blue book about DDD. There is also another book “Implementing Domain Driven Design” which covers a more practical approach and was recommended in a lot of talks as well.
Besides that, a lot of talks focused on testing topics (e.g. testing with Docker containers, CI/CD), on recent Java/JDK updates (e.g. license change; GraalVM to convert Java to native code) or on anything related to the Java world (e.g. how to run a business on open source code).
My Top 3 Talks
It’s a hard decision to present the best three talks, because there were a lot of good talks. I’ve decided to present talks where a) I’ve learned the most about the topic, b) which were presented in a good way and c) where you can also benefit from.
Web-API-Design in Java (by Stephan Müller)
Slides: click here
First statement of the talk: the API is the UI of a developer. I really like this quote. He continued to show the five different ways how to build an API: 1) REST, 2) GraphQL, 3) Server-side events, 4) web sockets, 5) Event Feeds. The main thing to remember is: REST is good to be used for cases where you have data with certain boundaries, i.e. you just return well-defined data, whereas GraphQL is really helpful if your data is interrelated und you need to do a lot of connections between them. In that case, you can save a lot of HTTP requests by doing one request to your GraphQL backend. The remaining talk was covering best practices. From documenting your API (e.g. using Open API Specification), correct error handling (e.g. never return a stack trace!), data validation (e.g. using Java Bean Validation) over security (e.g. don’t use BasicAuth, instead use JWT) to versioning of your API (e.g. using the URL or an Accept-Header with a versioned media type).
Read more: API Design Guidelines collection
I have to admit: I’m already using a lot of the presented best practices. But it’s always good to double-check that again from time to time. Are you using everything of that? For the German speaking people here, I can highly recommend the book “REST und HTTP” which is related to this topic. I’ve read it and it covers a lot of good recommendations with really good examples!
Microservices and Transactions (by Lars Röwekamp)
Slides: click here
The talk started by presenting why starbucks does not use two phase commits. The real world is often not transactional, so why should you? Do you really need transactions? Can you solve the problem on the business level instead? Often this is the case! If transactions are really necessary, then use one of the following strategies:
- Think about your service boundaries again. You can merge services if it makes sense, but try to avoid building a new monolith again.
- Use a gateway service for transactions using XA (eXtended Architecture) and a two-phase commit protocol. (I think I haven’t heard about the term “XA” before, but I do think it’s a bad idea to use a centralized gateway service to manage all transactions across different microservices)
- DIY two-phase commit XA gateway – simple conclusion: don’t do it at home.
- Transactions using the SAGA pattern. (I have to admit I haven’t heard about this pattern before) The basic principle is that you distribute business transactions into multiple technical ones, for example “create pending order” → “check & reserve credit limit” → “approve order with reserved credit limit”. In case of errors you have to stop and cancel (read: reset/redo) the previous operations. There are basically two ways to achieve this:
- using a choreography, meaning implicitly controlling the flow through events
- Problem: increasing complexity + your business code is distributed over your architecture
- using an orchestration, meaning explicitly controlling the flow by calling services directly with one master service → easier reset possible in case an error happens
- Problem: higher challenge to coordinate everything
- using a choreography, meaning implicitly controlling the flow through events
Recommendation: use choreography if the process is quite simple (e.g. less than 5 steps), otherwise use orchestration. However, it’s not as easy as it might sound. For example, what happens if a microservice dies while performing the transaction? How can it catch up again and maybe resume the previous work (if required) ? Hence he’s suggesting to use a framework to support you with that, for example Eventuate Tram Sagas.
There was another talk about this topic, called “Lost in Transaction? Data consistency in distibuted systems” by Bernd Ruecker, the founder of Camunda (a workflow engine to support such cases).
Btw. a book recommendation by Lars: “Microservices Patterns“.
Hitchhiker’s Guide to Serverless (by Lars Röwekamp)
Slides: click here
Using serverless in your app can lead to many different points of failures. Failures in your code, in the integration of functions or in services where you have no control of. Hence it’s necessary to use proper monitoring and testing of your functions.
Monitoring:
- DIY: build your own tracing and monitoring solution, e.g. using serverless functions, and store data in different services, so you can analyze them as needed
- Use cloud services: use already provided services like X-Ray or CloudWatch to monitor your metrics or inspect the runtime behaviour of your functions
- Use external services: in case of a multi-cloud strategy you have to use services independent of your cloud provider, e.g. logz.io or dashbird or ELK-tracing.
Monitoring Tips: monitor asynchronously (i.e. a user shouldn’t notice a higher latency because of monitoring), also monitor business relevant metrics (e.g. sales volumes, etc. → if this decreases unexpectedly, then you know something is wrong in your system)
Testing Tips:
- make sure to separate business logic and infrastructure glue code
- write unit tests (e.g. using JUnit), write integration tests (e.g. execute functions locally and mock certain services → saves you money), write end-to-end tests (e.g. by running your cloud locally or at least in a separate dev environment which you can shutdown as soon as the tests are done to save money)
If you have further questions to this topic, let me know about it! I hope you enjoyed this short summary of my JavaLand 2019 experience.