Archive for the ‘en-US’ Category
[DevoxxBE2023] REST Next Level: Crafting Domain-Driven Web APIs by Julien Topçu
At Devoxx Belgium 2023, Julien Topçu, a technical coach at Shadow, delivered a compelling session on elevating REST APIs by embedding domain-driven design principles. With a rich background in crafting software using Domain-Driven Design (DDD), Extreme Programming, and Kanban, Julien illuminated the pitfalls of traditional REST implementations and proposed a transformative approach to encapsulate business intent within APIs. His talk, centered around a fictional space travel booking system, demonstrated how to align APIs with user actions, preserve business workflows, and enhance consumer experience through hypermedia controls. Through a blend of theoretical insights and practical demonstrations, Julien showcased a methodology to create APIs that are not only functional but also semantically rich and workflow-driven.
The Pitfalls of Traditional REST APIs
Julien began by highlighting a pervasive issue in software architecture: the loss of business intent when translating domain logic into REST APIs. Typically, business logic resides in the backend to avoid duplication across consumers like web or mobile applications. However, REST’s uniform interface, with its limited vocabulary of CRUD operations (Create, Read, Update, Delete), often distorts this logic. For instance, in a train reservation system, a user’s intent to “search for trains” is reduced to “create a search resource,” stripping away domain-specific semantics like destinations or schedules. This mismatch, Julien argued, stems from REST’s standardized approach, formalized by Roy Fielding in his PhD thesis, which prioritizes simplicity over application-specific needs. As a result, APIs lose expressiveness, forcing consumers to reconstruct business workflows, leading to what Julien termed “accidental complexity of adaptation.”
To illustrate, Julien presented a scenario where a user performs a search for space trains from Earth to the Moon. The traditional REST API translates this into a POST request to create a search resource, devoid of domain context. This not only obscures the user’s intent but also couples consumers to the backend’s implementation, making changes—like switching from “bound” to “journey index” for multi-destination trips—disruptive. Julien’s live demo underscored this fragility: altering a request parameter broke the API, highlighting the risks of tight coupling between consumers and backend models.
Encapsulating Business Intent with Semantic Endpoints
To address these shortcomings, Julien proposed aligning REST endpoints with user actions rather than backend models. Instead of exposing implementation details, such as updating a sub-resource like “selection” within a search, APIs should reflect behaviors like “select a space train with a fare.” This approach involves using classifiers in URLs, such as POST /searches/{id}/spacetrains/{number}/fares/{code}/select, which clearly convey the intent of selecting a fare for a specific train. Julien emphasized that this does not violate REST principles, debunking the myth that verbs in URLs are forbidden. As long as verbs align with HTTP methods (e.g., POST for creating a resource), they enhance semantic clarity without breaking the uniform interface.
This shift decouples consumers from the backend’s internal structure. For example, changing the backend’s data model (e.g., using booleans instead of a selection object) no longer impacts consumers, as the API exposes behaviors rather than state. Julien’s demo further showcased this by demonstrating how a frontend could adapt to backend changes (e.g., from “bound” to “journey index”) without modification, thanks to semantic endpoints. This approach not only preserves business intent but also simplifies consumer logic, reducing the cognitive load of interpreting CRUD-based APIs.
Encapsulating Workflows with Hypermedia Controls
A critical challenge Julien addressed is the lack of workflow definition in traditional REST APIs. Typically, consumers must hardcode business workflows, such as the sequence of selecting outbound and inbound trains before booking. This leads to duplicated logic and potential errors, like displaying a booking button prematurely. Julien introduced hypermedia controls, specifically HATEOAS (Hypermedia As The Engine Of Application State), as a solution. By embedding links in API responses, the backend can guide consumers through the workflow dynamically.
In his demo, Julien showed how a search response includes links like select-outbound and all-inbounds, which guide the consumer to the next valid actions. For instance, after selecting an outbound train, the response provides a link to select an inbound train, ensuring only compatible options are available. This encapsulation of workflow logic in the backend eliminates the need for consumers to understand the sequence of actions, reducing errors and enhancing maintainability. Julien highlighted that this approach, part of the Richardson Maturity Model’s Level 3, makes APIs discoverable and resilient to backend changes, as consumers rely on links rather than hardcoded URLs.
Practical Implementation and Limitations
Julien’s live coding demo brought these concepts to life, showcasing a Spring Boot backend in Kotlin that dynamically generates links based on the application state. For example, the create-booking link only appears when the selection is complete, ensuring consumers cannot book prematurely. This dynamic guidance, facilitated by Spring HATEOAS, allows the frontend to display UI elements like the booking button based solely on available links, streamlining development and enhancing user experience.
However, Julien acknowledged limitations. For complex forms requiring extensive user input, the hypermedia approach may need supplementation with predefined payloads, as consumers must know what data to send. Additionally, long URLs, while not a practical issue in Julien’s experience at Expedia, could pose challenges in some contexts. Despite these constraints, the approach excels in domains with well-defined workflows, offering a robust framework for building expressive, maintainable APIs.
Conclusion: A New Paradigm for REST APIs
Julien’s session at Devoxx Belgium 2023 offered a transformative vision for REST APIs, emphasizing the power of domain-driven design and hypermedia controls. By aligning endpoints with user actions, encapsulating behaviors, and guiding workflows through links, developers can create APIs that are both semantically rich and resilient to change. This approach not only enhances consumer experience but also aligns with the principles of DDD, ensuring that business intent remains at the forefront of API design. Julien’s practical insights and engaging demo left attendees inspired to rethink their API strategies, fostering a deeper appreciation for REST’s potential when infused with domain-driven principles.
Links:
[DevoxxBE2023] The Panama Dojo: Black Belt Programming with Java 21 and the FFM API by Per Minborg
In an engaging session at Devoxx Belgium 2023, Per Minborg, a Java Core Library team member at Oracle and an OpenJDK contributor, guided attendees through the intricacies of the Foreign Function and Memory (FFM) API, a pivotal component of Project Panama. With a blend of theoretical insights and live coding, Per demonstrated how this API, in its third preview in Java 21, enables seamless interaction with native memory and functions using pure Java code. His talk, dubbed the “Panama Dojo,” showcased the API’s potential to enhance performance and safety, culminating in a hands-on demo of a lightweight microservice framework built with memory segments, arenas, and memory layouts.
Unveiling the FFM API’s Capabilities
Per introduced the FFM API as a solution to the limitations of Java Native Interface (JNI) and direct buffers. Unlike JNI, which requires cumbersome C stubs and inefficient data passing, the FFM API allows direct native memory access and function calls. Per illustrated this with a Point struct example, where a memory segment models a contiguous memory region with 64-bit addressing, supporting both heap and native segments. This eliminates the 2GB limit of direct buffers, offering greater flexibility and efficiency.
The API introduces memory segments with constraints like size, lifetime, and thread confinement, preventing out-of-bounds access and use-after-free errors. Per highlighted the importance of deterministic deallocation, contrasting Java’s automatic memory management with C’s manual approach. The FFM API’s arenas, such as confined and shared arenas, manage segment lifecycles, ensuring resources are freed explicitly, as demonstrated in a try-with-resources block that deterministically deallocates a segment.
Structuring Memory with Layouts and Arenas
Memory layouts, a key FFM API feature, provide a declarative way to define memory structures, reducing manual offset computations. Per showed how a Point layout with x and y doubles uses var handles to access fields safely, leveraging JIT optimizations for atomic operations. This approach minimizes bugs in complex structs, as var handles inherently account for offsets, unlike manual calculations.
Arenas further enhance safety by grouping segments with shared lifetimes. Per demonstrated a confined arena, restricting access to a single thread, and a shared arena, allowing multi-threaded access with thread-local handshakes for safe closure. These constructs bridge the gap between C’s flexibility and Rust’s safety, offering a balanced model for Java developers. In his live demo, Per used an arena to allocate a MarketInfo segment, showcasing deterministic deallocation and thread safety.
Building a Persistent Queue with Memory Mapping
The heart of Per’s session was a live coding demo constructing a persistent queue using memory mapping and atomic operations. He defined a MarketInfo record for stock exchange data, including timestamp, symbol, and price fields. Using a record mapper, Per serialized and deserialized records to and from memory segments, demonstrating immutability and thread safety. The mapper, a potential future JDK feature, simplifies data transfer between Java objects and native memory.
Per then implemented a memory-mapped queue, where a file-backed segment stores headers and payloads. Headers use atomic operations to manage mutual exclusion across threads and JVMs, ensuring safe concurrent access. In the demo, a producer appended MarketInfo records to the queue, while two consumers read them asynchronously, showcasing low-latency, high-performance data sharing. Per’s use of sparse files allowed a 1MB queue to scale virtually, highlighting the API’s efficiency.
Crafting a Microservice Framework
The session culminated in assembling these components into a microservice framework. Per’s queue, inspired by Chronicle Queue, supports persistent, high-performance data exchange across JVMs. The framework leverages memory mapping for durability, atomic operations for concurrency, and record mappers for clean data modeling. Per demonstrated its practical application by persisting a queue to a file and reading it in a separate JVM, underscoring its robustness for distributed systems.
He emphasized the reusability of these patterns across domains like machine learning and graphics processing, where native libraries are prevalent. Tools like jextract, briefly mentioned, further unlock native libraries like TensorFlow, enabling Java developers to integrate them effortlessly. Per’s framework, though minimal, illustrates how the FFM API can transform Java’s interaction with native code, offering a safer, faster alternative to JNI.
Performance and Safety in Harmony
Throughout, Per stressed the FFM API’s dual focus on performance and safety. Native function calls, faster than JNI, and memory segments with strict constraints outperform direct buffers while preventing common errors. The API’s integration with existing JDK features, like var handles, ensures compatibility and optimization. Per’s live coding, despite its complexity, flowed seamlessly, reinforcing the API’s practicality for real-world applications.
Conclusion: Embracing the Panama Dojo
Per’s session was a masterclass in leveraging the FFM API to push Java’s boundaries. By combining memory segments, layouts, arenas, and atomic operations, he crafted a framework that exemplifies the API’s potential. His call to action—experiment with the FFM API in Java 21—invites developers to explore this transformative tool, promising enhanced performance and safety for native interactions. The Panama Dojo left attendees inspired to break new ground in Java development.
Links:
[DevoxxBE2023] Java Language Update by Brian Goetz
At Devoxx Belgium 2023, Brian Goetz, Oracle’s Java Language Architect, delivered an insightful session on the evolution of Java, weaving together a narrative of recent advancements, current features in preview, and a vision for the language’s future. With his deep expertise, Brian illuminated how Java balances innovation with compatibility, ensuring it remains a cornerstone of modern software development. His talk explored the introduction of records, sealed classes, pattern matching, and emerging features like string templates and simplified program structures, all designed to enhance Java’s expressiveness and accessibility. Through a blend of technical depth and practical examples, Brian showcased Java’s commitment to readable, maintainable code while addressing contemporary programming challenges.
Reflecting on Java’s Recent Evolution
Brian began by recapping Java’s significant strides since his last Devoxx appearance, highlighting features like records, sealed classes, and pattern matching. Records, introduced as nominal tuples, provide a concise way to model data with named components, enhancing readability over structural tuples. For instance, a Point record with x and y coordinates is more intuitive than an anonymous tuple of integers. By deriving constructors, accessors, and equality methods from a state declaration, records eliminate boilerplate while making a clear semantic statement about data immutability. Brian emphasized that this semantic focus, rather than mere syntax reduction, distinguishes Java’s approach from alternatives like Lombok.
Sealed classes, another recent addition, allow developers to restrict class hierarchies, specifying permitted subtypes explicitly. This enables libraries to expose abstract types while controlling implementations, as seen in the JDK’s use of method handles. Sealed classes also enhance exhaustiveness checking in switch statements, reducing runtime errors by ensuring all cases are covered. Brian illustrated this with a Shape hierarchy, where a sealed interface permits only Circle and Rectangle, allowing the compiler to verify switch completeness without a default clause.
Advancing Data Modeling with Pattern Matching
Pattern matching, a cornerstone of Java’s recent enhancements, fuses type testing, casting, and binding into a single operation, reducing errors from manual casts. Brian demonstrated how type patterns, like if (obj instanceof String s), streamline code by eliminating redundant casts. Record patterns extend this by deconstructing objects into components, enabling recursive matching for nested structures. For example, a Circle record with a Point center can be matched to extract x and y coordinates in one expression, enhancing both concision and safety.
The revamped switch construct, now an expression supporting patterns and guards, further leverages these capabilities. Brian highlighted its exhaustiveness checking, which uses sealing information to ensure all cases are handled, as in a Color interface sealed to Red, Yellow, and Green. This eliminates the need for default clauses, catching errors at compile time if the hierarchy evolves. By combining records, sealed classes, and pattern matching, Java now supports algebraic data types, offering a powerful framework for modeling complex domains like expressions, where a sealed Expression type can be traversed elegantly with pattern-based recursion.
Introducing String Templates for Safe Aggregation
Looking to the future, Brian introduced string templates, a preview feature addressing the perils of string interpolation. Unlike traditional concatenation or formatting methods, string templates use a template processor to safely combine text fragments and expressions. A syntax like STR.FMT."Hello, \{name\}!" invokes a processor to validate inputs, preventing issues like SQL injection. Brian envisioned a SQL template processor that balances quotes and produces a result set directly, bypassing string intermediaries for efficiency and security. Similarly, a JSON processor could streamline API development by constructing objects from raw fragments, enhancing performance.
This approach reframes interpolation as a broader aggregation problem, allowing developers to define custom processors for domain-specific needs. Brian’s emphasis on safety and flexibility underscores Java’s commitment to robust APIs, drawing inspiration from JavaScript’s tagged functions and Scala’s string interpolators, but tailored to Java’s ecosystem.
Simplifying Java’s On-Ramp and Beyond
To make Java for new developers, Brian discussed preview features like unnamed classes and patterns, which reduce boilerplate for simple programs. A minimal program might omit public static void main, allowing beginners to focus on core logic rather than complex object-oriented constructs. This aligns Java with languages like Python, where incremental learning is prioritized, easing the educational burden on instructors and students alike.
Future enhancements include reconstruction patterns for immutable objects, enabling concise updates like p.with(x: 0) to derive new records from existing ones. Brian also proposed deconstructor patterns for regular classes, mirroring constructors to enable pattern decomposition, enhancing API symmetry. These features aim to make aggregation and decomposition reversible, reducing error-prone asymmetries in object manipulation. For instance, a Person class could declare a deconstructor to extract first and last names, mirroring its constructor, streamlining data handling across Java’s object model.
Conclusion: Java’s Balanced Path Forward
Brian’s session underscored Java’s deliberate evolution, balancing innovation with compatibility. By prioritizing readable, maintainable code, Java addresses modern challenges like loosely coupled services and untyped data, positioning itself as a versatile language for data modeling. Features like string templates and simplified program structures promise greater accessibility, while pattern matching and deconstruction patterns enhance expressiveness. As Java continues to refine its features, it remains a testament to thoughtful design, ensuring developers can build robust, future-ready applications.
Links:
[AWS Summit Berlin 2023] Go-to-Market with Your Startup: Tips and Best Practices from VC Investors
At AWS Summit Berlin 2023, David Roldán, Head of Startup Business Development for EMEA at AWS, led a 48-minute panel, available on YouTube, featuring VC investors and operators: Constantine, CTO and co-founder of PlanRadar, Jasper, partner at Cherry Ventures, and Gloria, founder of Beyond Capital. This post, targeting startup founders, explores go-to-market (GTM) strategies for B2B SaaS, emphasizing product-segment fit, iterative processes, and avoiding premature scaling in a competitive landscape with over 100,000 independent software vendors.
Defining Product-Segment Fit
Jasper introduced the concept of product-segment fit, arguing it’s more precise than product-market fit for early-stage startups. He emphasized that founders should target a specific customer segment where the product resonates strongly, rather than chasing universal appeal. For example, PlanRadar, serving the construction industry, found success by focusing on old-fashioned outbound sales to reach decision-makers in a niche vertical. Gloria reinforced this, noting that chasing a single “killer feature” often distracts from solving core use cases. Instead, founders should iterate based on customer feedback, ensuring the product delivers immediate value to a well-defined audience, avoiding dilution of focus across disparate segments.
Iterative GTM Strategies
Constantine shared PlanRadar’s journey, highlighting the iterative nature of GTM. With a five-founder team spanning commercial, industry, and tech expertise, PlanRadar prioritized early customer feedback over polished features. He advised launching minimum viable products to test assumptions, even if imperfect, to refine offerings rapidly. Gloria added that data infrastructure, like a well-structured CRM, is critical before Series A to track sales cycles and conversion stages. However, Jasper cautioned against over-rationalizing early GTM with tools like Salesforce, which can burden seed-stage startups. Instead, founders should stay hands-on, engaging directly with customers to build velocity in the sales pipeline.
Avoiding Premature Scaling
Gloria and Constantine stressed the dangers of premature scaling, particularly in hiring. Gloria advised against hiring product managers too early, recommending product engineers who can own the roadmap alongside founders until post-Series A. Constantine echoed this, noting PlanRadar delayed building a product management team until after Series A due to workload and complexity, hiring an ex-founder after a year-long search. Jasper highlighted that premature hires, like sales managers craving predictability, can push startups to scale in the wrong segment, leading to misaligned products. The panel agreed that founders must retain product vision, avoiding delegation to non-founders who lack the same long-term perspective.
Customer Success and Retention
Retention emerged as a key GTM metric, but its priority depends on stage. Gloria argued that early churn is acceptable to refine product-segment fit, but post-product-market fit, net retention becomes critical, reflecting customer love through renewals and upsells. Constantine detailed PlanRadar’s post-Series A customer success team, which segments customers (gold, silver, bronze) using usage data to allocate scarce resources effectively. He noted charging for onboarding, common in Europe, boosts engagement by signaling value. Gloria emphasized three pillars: activation (fast onboarding), engagement (tracking feature usage), and renewals (modularizing products for cross-selling), ensuring startups maximize lifetime value as they scale.
[KotlinConf2023] Dissecting Kotlin: Exploring Idiomatic Usage of Sealed Types, SAMs, and More with Huyen Tue Dao
Huyen Tue Dao, a respected Android and Kotlin developer (formerly of Trello, more recently Lead Android Developer at Adobe), returned to KotlinConf’23 with her insightful talk, “Dissecting Kotlin: Unsealing the Sealed, the SAM, and Other Syntax”. Continuing her exploration of what constitutes “idiomatic Kotlin,” Huyen examined several language and library features introduced or refined over the past few years, delving into their semantics, syntax, and underlying implementations to understand their best use cases and how they fit into Kotlin’s broader themes. She referenced Andre Breslav’s 2018 KotlinConf keynote, which emphasized Kotlin’s pragmatic goals: readability over concision, reuse over expressiveness, interoperability, and safety/tooling.
Huyen’s approach involved dissecting features to see if they guide developers toward more idiomatic Kotlin or present choices where idiomatic usage might be nuanced.
Sealed Hierarchies: Evolution and Flexibility
Huyen began by revisiting sealed classes and interfaces, a cornerstone for modeling restricted hierarchies, often used for representing states or a fixed set of types. Key evolutions she discussed include:
* Sealed Interfaces (Kotlin 1.5): Previously, sealed hierarchies were restricted to sealed class and abstract class. The introduction of sealed interface provided more flexibility, allowing classes to implement multiple sealed interfaces and enabling a wider range of domain modeling possibilities. She illustrated this by evolving a movie genre example, initially a sealed class, to use sealed interfaces for sub-genres, demonstrating how a class (e.g., a specific movie) could belong to multiple genre classifications.
* Unsealing Sealed Classes (Implicitly): While not “unsealing” in the sense of breaking the restriction, the ability for subclasses of sealed classes to be defined in different files within the same compilation unit and module (introduced before Kotlin 1.5 for sealed classes, and a natural fit for sealed interfaces) offers more organizational flexibility for larger hierarchies.
* Data Objects (Kotlin 1.9): For singleton instances within a sealed hierarchy (or elsewhere) that benefit from data class-like behavior (e.g., a meaningful toString()), Kotlin 1.9 introduced data object. This combines the singleton nature of object with the auto-generated toString, equals, and hashCode methods of data classes, providing a cleaner way to represent simple, named instances in a hierarchy.
A “bytecode break” showed that sealed classes are compiled as abstract classes with private constructors and that their permitted subclasses are often checked using instanceof and specific class metadata generated by the compiler.
Unsigned Integers and Value Classes: Expressiveness and Performance
Huyen then explored features aimed at enhancing expressiveness and performance around data representation:
* Unsigned Integer Types (UByte, UShort, UInt, ULong – Stable in Kotlin 1.5): These types provide a way to represent non-negative numbers, utilizing the full bit-width for the magnitude. This is particularly useful when interacting with native APIs (like C++) that use unsigned types, or when dealing with data where negative values are meaningless (e.g., quantities, bitmasks). They come with their own set of operations and ranges. Huyen highlighted how they avoid the complexities of two’s complement interpretation when only positive values are needed.
* Value Classes (Inline Classes became Value Classes, stable with JVM backend in Kotlin 1.5): Value classes (@JvmInline value class) are wrappers around a single underlying property. Their primary benefit is providing type safety for primitive-like data (e.g., Email, UserId, Frequency) without the runtime overhead of heap allocation for the wrapper object in many cases. When possible, the compiler “inlines” the value, using the underlying type directly in bytecode, thus avoiding object allocation and offering performance benefits similar to primitives while retaining type distinction at compile time. Huyen used an audio processing example with distinct types like Frequency, SamplingRate, and FramesPerBuffer to illustrate how value classes can prevent accidental misuse of simple types like Int or Float.
SAM Conversions and Functional Interfaces: Java Interop and Kotlin Idiom
Finally, Huyen discussed Single Abstract Method (SAM) interfaces and Kotlin’s fun interface:
* SAM Conversions for Java Interfaces: Kotlin has long supported SAM conversions for Java interfaces, allowing a lambda to be used where an instance of a Java interface with a single abstract method is expected.
* fun interface (Kotlin 1.4): To enable similar idiomatic usage for Kotlin-defined interfaces, Kotlin introduced fun interface. By marking a Kotlin interface with the fun keyword, developers explicitly opt-in to SAM conversion, allowing a lambda to be directly passed where an instance of that interface is required. This promotes a more functional style and reduces boilerplate for simple callback-like interfaces. This feature aims to provide compatible syntax between Java and Kotlin code for functional interfaces.
Huyen concluded by reiterating that while understanding syntax and semantics is helpful, “idiomatic Kotlin” ultimately is about what best solves the problem at hand for the developer and their team, aligning with Kotlin’s pragmatic principles.
Links:
[PHPForumParis2022] Once Upon a Time… Web Browsers – Noël Macé and Pierre Tibulle
Noël Macé and Pierre Tibulle, passionate advocates for web standards, delivered a captivating narrative at PHP Forum Paris 2022, tracing the evolution of web browsers from their inception to the present day. Their talk, structured as a historical journey, began with Tim Berners-Lee’s pioneering work at CERN in 1980 and explored the technological and ethical shifts that shaped the modern web. Noël and Pierre’s engaging delivery, enriched with anecdotes, offered developers a deeper understanding of browsers’ impact on PHP development and user privacy.
The Birth of the Web
Noël and Pierre opened with Tim Berners-Lee’s creation of the first browser interface at CERN, designed to manage particle accelerators with a simple 24-line, 64-character display. This foundational work laid the groundwork for the World Wide Web, introduced in 1991. They described the rapid evolution of early browsers like Mosaic and Netscape, which introduced graphical interfaces, transforming the web into a user-friendly platform and setting the stage for PHP’s role in dynamic web applications.
Browser Wars and Standardization
The presenters chronicled the intense browser wars of the 1990s, where Netscape and Internet Explorer competed for dominance, often at the cost of compatibility. They highlighted the formation of the W3C and its role in standardizing web technologies, ensuring cross-browser consistency. Noël and Pierre emphasized how these standards, driven by open collaboration, enabled PHP developers to build reliable, cross-platform applications, underscoring the importance of adhering to W3C guidelines in modern development.
Privacy and Ethical Considerations
Shifting to contemporary challenges, Noël and Pierre addressed the growing importance of user privacy. They recommended tools like Privacy Badger and Firefox to mitigate tracking, noting issues like GitHub’s editor requiring data collection for basic functionality. By advocating for active engagement with the W3C’s open discussions on GitHub, they encouraged developers to influence web standards, ensuring browsers align with ethical values and support privacy-focused PHP applications.
Shaping the Future of the Web
Concluding, Noël and Pierre inspired developers to contribute to the web’s evolution by participating in W3C discussions and reporting issues to platforms like GitHub. Their call to action emphasized the developer’s role in advocating for a user-respecting web. By blending historical context with practical advice, they provided PHP developers with a roadmap to navigate browser-related challenges, fostering a more inclusive and ethical digital landscape.
Links:
[SpringIO2023] Spring Framework 6.1: Infrastructure Revisited by Juergen Hoeller
At Spring I/O 2023 in Barcelona, Juergen Hoeller, a pivotal figure in the Spring Framework, delivered an insightful session on the upcoming Spring Framework 6.1, focusing on its alignment with cutting-edge JVM innovations. Building on themes introduced in the conference keynote, Juergen explored how Spring Framework 6.1 integrates with OpenJDK’s Project Loom (virtual threads) and CRaC (Checkpoint/Restore), empowering developers to leverage these advancements for scalable, efficient applications. With Spring Framework 6.1 and Spring Boot 3.2 set for release in November 2023, this talk offered a forward-looking perspective on infrastructure enhancements already available in snapshots and slated for the first milestone in June 2023.
Modern Java and Jakarta EE Context
Juergen set the stage by outlining the Java and Jakarta EE landscape that Spring Framework 6.1 inhabits. Spring Framework 6.0 established a JDK 17 baseline, introducing language innovations like record types, sealed classes, and pattern matching, which provide a robust foundation for modern Java development. JDK 21, a long-term support release arriving in September 2023, builds on this with further enhancements, including sequence collections and virtual threads exiting preview. Spring Framework 6.1 aligns with JDK 21, enabling developers to adopt these features seamlessly. On the Jakarta EE front, Spring Framework 6.1 supports Jakarta EE 10, with plans to align with Jakarta EE 11’s anticipated JDK 21 requirement in 2024. This ensures compatibility with evolving servlet, JPA, and bean validation APIs, positioning Spring as a bridge to future Java ecosystems.
Virtual Threads: Scalability with Simplicity
A cornerstone of Juergen’s talk was Spring Framework 6.1’s integration with virtual threads, a transformative JVM feature in JDK 21. Virtual threads, lightweight and JVM-managed, allow blocking operations without tying up platform threads, enabling massive scalability with minimal resource overhead. Juergen explained that Spring’s task executor facilities, like SimpleAsyncTaskExecutor and a dedicated VirtualThreadTaskExecutor, are now virtual thread-ready. These allow developers to replace traditional thread pool configurations with virtual thread setups, requiring minimal code changes. In Spring MVC, virtual threads are configured at the servlet container level (e.g., Tomcat or Jetty), with upcoming Tomcat releases offering first-class support. For reactive stacks like Spring WebFlux, virtual threads serve as an escape hatch for integrating blocking operations, complementing the reactive model’s efficiency. Juergen emphasized that existing Spring MVC applications can achieve higher scalability or reduced memory footprints by adopting virtual threads, with no application code changes in ideal scenarios.
Checkpoint/Restore: Revolutionizing Startup Time
Juergen also delved into Spring Framework 6.1’s support for Project CRaC, which dramatically accelerates application startup through JVM snapshotting. By capturing a fully bootstrapped application state—potentially after warmup—and restoring it on demand, CRaC reduces startup times by a factor of at least 20 compared to traditional JVM bootstrapping. Spring Framework 6.1 integrates CRaC via its lifecycle model, using the 14-year-old Lifecycle interface to manage component stop and restart signals during checkpoint and restore phases. This ensures that embedded servers, message listeners, and other components pause cleanly and resume seamlessly. Juergen noted that most Spring applications are CRaC-compatible out of the box, though some components, like Tomcat adapters, require updates. Spring Boot 3.2 may introduce standard checkpoint options post-bootstrap, simplifying adoption. Currently supported by Azul’s OpenJDK and AWS Lambda SnapStart, CRaC promises significant benefits for dynamic scaling in Linux container deployments.
Practical Adoption and Future Outlook
Juergen underscored the practical readiness of these features, with Spring Framework 6.1 M1 slated for mid-June 2023 and Spring Boot 3.2 M1 for mid-July. Release candidates are planned for October, aligning with JDK 21’s September release, ensuring developers can adopt virtual threads and CRaC promptly. He encouraged experimentation, noting that benchmarking virtual threads or CRaC with existing applications is the best way to quantify benefits like scalability or reduced startup times. Looking ahead, Juergen highlighted a Spring.Next Buff session at Spring I/O for deeper discussions on these innovations. By aligning with JDK 21 and Jakarta EE 11, Spring Framework 6.1 positions developers to embrace the Java ecosystem’s future, delivering performance and efficiency without sacrificing Spring’s hallmark simplicity.
Links:
[DevoxxBE 2023] Introducing Flow: The Worst Software Development Approach in History
In a satirical yet insightful closing keynote at Devoxx Belgium 2023, Sander Hoogendoorn and Kim van Wilgen, seasoned software development experts, introduced “Flow,” a fictional methodology designed to expose the absurdities of overly complex software development practices. With humor and sharp critique, Sander and Kim drew from decades of experience to lampoon methodologies like Waterfall, Scrum, SAFe, and Spotify, blending real-world anecdotes with exaggerated principles to highlight what not to do. Their talk, laced with wit, ultimately transitioned to earnest advice, advocating for simplicity, autonomy, and human-centric development. This presentation offers a mirror to the industry, urging developers to critically evaluate methodologies and prioritize effective, enjoyable work.
The Misadventure of Methodologies
Sander kicked off with a historical detour, debunking the myth of Waterfall’s rigidity. Citing Winston Royce’s 1970 paper, he revealed that Waterfall was meant to be iterative, allowing developers to revisit phases—a concept ignored for decades, costing billions. This set the stage for Flow, a methodology born from a tongue-in-cheek desire to maximize project duration for consultancy profits. Kim explained how they cherry-picked the worst elements from existing frameworks: endless sprints from Scrum, gamification to curb autonomy, and an alphabet soup of roles from SAFe.
Their critique was grounded in real-world failures. Sander shared a Belgian project where misestimated sprints and 300 outsourced developers led to chaos, exacerbated by documentation in Dutch and French. Kim highlighted how methodologies like SAFe balloon roles, sidelining customers and adding complexity. By naming Flow with trendy buzzwords—Kaizen, continuous disappointment, and pointless—they mocked the industry’s obsession with jargon over substance.
The Flow Framework: A Recipe for Dysfunction
Flow’s principles, as Sander and Kim outlined, are deliberately counterproductive. Sprints, renamed “mini-Waterfalls,” ensure repeated failures, with burn charts (not burn-down charts) showing growing work without progress. Meetings, dubbed “Flow meetings,” are scheduled to disrupt developers’ focus, with random topics and high-placed interruptions—like a 2.5-meter-tall CEO bursting in. Kim emphasized gamification, stripping teams of real autonomy while offering trivial perks like workspace decoration, exemplified by a ball pit job interview at a Dutch e-commerce firm.
The Flow Manifesto, a parody of the Agile Manifesto, prioritizes “extensive certification over hands-on experience” and “meetings over focus.” Sander recounted a project in France with a 20-column board so confusing that even AI couldn’t decipher its French Post-its. Jira, mandatory in Flow, becomes a tool for obfuscation, with requirements buried in lengthy tickets. Open floor plans and Slack further stifle communication, with “pair slacking” replacing collaboration, ensuring developers remain distracted and disconnected.
Enterprise Flow: Scaling the Absurdity
In large organizations, Flow escalates into the Big Flow Framework (BFF), starting at version 3.0 to sound innovative. Kim critiqued the blind adoption of Spotify’s model, designed for 8x annual growth, which saddles banks with excessive managers—sometimes a 1:1 ratio with developers. Sander recounted a client renaming managers as “tech leads,” adding 118 unnecessary roles to a release train. Certifications, costing €10,000 per recertification, parody the industry’s profit-driven training schemes.
Flow’s tooling, like boards with incomprehensible columns and Jira’s dual Scrum-Kanban confusion, ensures clients remain baffled. Kim highlighted how Enterprise Flow thrives on copying trendy startups like Basecamp, debating irrelevant issues like banning TypeScript or leaving public clouds. Research, they noted, shows no methodology—including SAFe or LeSS—outperforms having none, underscoring Flow’s satirical point: complexity breeds failure.
A Serious Turn: Principles for Better Development
After the laughter, Sander and Kim pivoted to their true beliefs, advocating for a human-centric approach. Software, they stressed, is built by people, not tools or methodologies. Teams should evolve their own practices, using Scrum or Kanban as starting points but adapting to context. Face-to-face communication, trust, and psychological safety are paramount, as red sprints and silencing voices drive talent away.
Focus is sacred, requiring quiet spaces and flexible hours, as ideas often spark outside 9–5. Continuous learning, guarded by dedicating at least one day weekly, prevents stagnation. Autonomy, though initially uncomfortable, empowers teams to make decisions, as Sander’s experience with reluctant developers showed. Flat organizations with minimal hierarchy foster trust, while experienced developers, like those born in the ’60s and ’70s, mentor through code reviews rather than churning out code.
Conclusion: Simplicity and Joy in Development
Sander and Kim’s Flow is a cautionary tale, urging developers to reject bloated methodologies and embrace simplicity. By reducing complexity, as Albert Einstein suggested, teams can deliver value effectively. Above all, they reminded the audience to have fun, celebrating software development as the best industry to be in. Their talk, blending satire with wisdom, inspires developers to craft methodologies that empower people, foster collaboration, and make work enjoyable.
Links:
Hashtags: #SoftwareDevelopment #Agile #Flow #Methodologies #DevOps #SanderHoogendoorn #KimVanWilgen #SchubergPhilis #iBOOD #DevoxxBE2023
[DevoxxBE 2023] The Great Divergence: Bridging the Gap Between Industry and University Java
At Devoxx Belgium 2023, Felipe Yanaga, a teaching assistant at the University of North Carolina at Chapel Hill and a Robertson Scholar, delivered a compelling presentation addressing the growing disconnect between the vibrant use of Java in industry and its outdated perception in academia. As a student with internships at Amazon and Google, and a fellow at UNC’s Computer Science Experience Lab, Felipe draws on his unique perspective to highlight how universities lag in teaching modern Java practices. His talk explores the reasons behind this divergence, the negative perceptions students hold about Java, and actionable steps to revitalize its presence in academic settings.
Java’s Strength in Industry
Felipe begins by emphasizing Java’s enduring relevance in the professional world. Far from the “Java is dead” narrative that periodically surfaces online, the language thrives in industry, powered by innovations like Quarkus, GraalVM, and a rapid six-month release cycle. Companies sponsoring Devoxx, such as Red Hat and Oracle, exemplify Java’s robust ecosystem, leveraging frameworks and tools that enhance developer productivity. For instance, Felipe references the keynote by Brian Goetz, which outlined Java’s roadmap, showcasing its adaptability to modern development needs by drawing inspiration from other languages. This continuous evolution ensures Java remains a cornerstone for enterprise applications, from microservices to large-scale systems.
However, Felipe points out a troubling trend: despite its industry strength, Java’s popularity is declining in metrics like GitHub’s language rankings and the TIOBE Index. While JavaScript and Python have surged, Java’s share of relevant Google searches has dropped from 26% in 2002 to under 10% by 2023. Felipe attributes this partly to a shift in academic settings, where the foundation for programming passion is often laid. The disconnect between industry innovation and university curricula is a critical issue that needs addressing to sustain Java’s future.
The Academic Lag: Java’s Outdated Image
In universities, Java’s reputation suffers from outdated teaching practices. Felipe notes that many institutions, including top U.S. universities, have shifted introductory courses from Java to Python, citing Java’s perceived complexity and age. A 2017 quote from a Stanford professor illustrates this sentiment, claiming Java “shows its age” and prompting a move to Python for introductory courses. Surveys of 70 leading U.S. universities confirm this trend, with Python now dominating as the primary teaching language, while Java is relegated to data structures or object-oriented programming courses.
Felipe’s own experience at UNC-Chapel Hill reflects this shift. A decade ago, Java dominated the curriculum, but by 2023, Python had overtaken introductory and database courses. This transition reinforces a perception among students that Java is verbose, bloated, and outdated. Felipe conducted a survey among 181 students in a software engineering course, revealing stark insights: 42% believed Python was in highest industry demand, 67% preferred Python for building REST APIs, and terms like “tedious,” “boring,” and “outdated” dominated a word cloud describing Java. One student even remarked that Java is suitable only for maintaining legacy code, a sentiment that underscores the stigma Felipe aims to dismantle.
The On-Ramp Challenge: Simplifying Java’s Introduction
A significant barrier to Java’s adoption in academia is its steep learning curve for beginners. Felipe contrasts Python’s straightforward “hello world” with Java’s intimidating boilerplate code, such as public static void main. This complexity overwhelms novices, who grapple with concepts like classes and static methods without clear explanations. Instructors often dismiss these as “magic,” which disengages students and fosters a negative perception. Felipe highlights Java’s JEP 445, which introduces unnamed classes and instance main methods to reduce boilerplate, as a promising step to make Java more accessible. By simplifying the initial experience, such innovations could align Java’s on-ramp with Python’s ease, engaging students early and encouraging exploration.
Beyond the language itself, the Java ecosystem poses additional challenges. Installing Java is daunting for beginners, with multiple Oracle websites offering conflicting instructions. Felipe recounts his own struggle as a student, only navigating this thanks to his father’s guidance. Tools like SDKMan and JBang simplify installation and scripting, but these are often unknown to students outside the Java community. Similarly, choosing an IDE—IntelliJ, Eclipse, or VS Code—adds another layer of complexity. Felipe advocates for clear, standardized guidance, such as recommending SDKMan and IntelliJ, to streamline the learning process and make Java’s ecosystem more approachable.
Bridging the Divide: Community and Mentorship
To reverse the declining trend in academia, Felipe proposes actionable steps centered on community engagement. He emphasizes the need for industry professionals to connect with universities, citing examples like Tom from Info Support, who collaborates with local schools to demonstrate Java’s real-world applications. By mentoring students and updating professors on modern tools like Maven, Gradle, and Quarkus, industry can reshape Java’s image. Felipe also encourages inviting students to Java User Groups (JUGs), where they can interact with professionals and discover tools that enhance Java development. These initiatives, he argues, plant seeds of enthusiasm that students will share with peers, amplifying Java’s appeal.
Felipe stresses that small actions, like a 10-minute conversation with a student, can make a significant impact. By demystifying stereotypes—such as Java being slow or bloated—and showcasing frameworks like Quarkus with hot reload capabilities, professionals can counter misconceptions. He also addresses the lack of Java-focused workshops compared to Python and JavaScript, urging the community to actively reach out to students. This collective effort, Felipe believes, is crucial to ensuring the next generation of developers sees Java as a vibrant, modern language, not a relic of the past.
Links:
-
University of North Carolina at Chapel Hill
-
Duke University
Hashtags: #Java #SoftwareDevelopment #Education #Quarkus #GraalVM #UNCChapelHill #DukeUniversity #FelipeYanaga
[NodeCongress2023] Building a Modular Monolith in Node.js: The Fastify Architecture for Scalable Development
Lecturer: Matteo Collina
Matteo Collina is the Co-Founder and Chief Technology Officer (CTO) of Platformatic.dev, focusing on reducing friction in backend development. He is a prominent figure in the JavaScript and Node.js open-source communities, serving as a member of the Node.js Technical Steering Committee (TSC), concentrating on streams, diagnostics, and HTTP. Dr. Collina is the creator and maintainer of several foundational Node.js projects, including the high-performance web framework Fastify and the super-fast JSON logger Pino. He completed his Ph.D. in 2014, with his thesis focusing on “Application Platforms for the Internet of Things”.
- Institutional Profile/Professional Page: nodeland.dev
- X (Twitter): @matteocollina
- LinkedIn: in/matteocollina
- Organization: Platformatic.dev
Abstract
This article explores the architectural pattern of the modular monolith as a superior alternative to monolithic or premature microservice designs in the Node.js ecosystem, using the Fastify framework as the primary methodology. The analysis highlights how Fastify’s plugin system allows developers to create well-organized, testable, and maintainable applications by enforcing clear separation of concerns and rigorously avoiding the anti-pattern of global Singletons. Furthermore, it details how this architectural choice establishes a robust foundation that facilitates a near-frictionless migration to a microservices architecture when required.
Context: The Challenge of Free-Form Development
The inherent flexibility of the Node.js development model—while powerful—often leads to organizational and structural issues in large codebases, frequently resulting in “big ball of mud” monoliths. A key contributor to this technical debt is the liberal use of Singletons, global objects (like a database connection or configuration store) that hide dependencies and make components non-reusable and difficult to test in isolation.
Methodology: Fastify and the Modular Monolith
The proposed solution is the modular monolith, implemented using Fastify’s architectural features:
- Fastify Plugin System: Fastify’s core design dictates that any component (routes, business logic, configuration) must be encapsulated as a plugin. This system is fundamentally based on a Directed Acyclic Graph (DAG) architecture.
- Encapsulation and Scoping: When a plugin registers a dependency (e.g., a database connection), it gets its own encapsulated scope. Subsequent plugins registered underneath it inherit that dependency, but plugins registered in parallel do not. This rigorous encapsulation is the mechanism that prevents global Singletons, ensuring clear dependency flow and isolation of modules.
- Code-First Configuration: Using tools like
platformatic/service, the structure of the application—including plugins, databases, and general configuration—can be defined declaratively in a single configuration file.
Analysis of Implications
The modular monolith, when built with this methodology, offers significant consequences for engineering workflow and application lifecycle:
- Improved Testability and Organization: The strict encapsulation ensures that each module (plugin) can be tested in isolation, knowing precisely its inputs and outputs, leading to a codebase that can “stand the test of time”.
- Production Readiness: The architecture easily accommodates production-level features such as automatic OpenAPI documentation and Prometheus metrics integration via simple configuration toggles.
- Seamless Microservice Migration: By maintaining clear separation of concerns and avoiding shared state (i.e., a “share nothing architecture”), the architectural components created as Fastify plugins are already structurally prepared to be extracted into independent microservices. The transition is reduced to primarily a configuration step, validating the modular monolith as an intelligent starting point.
Conclusion
The use of Fastify to architect a modular monolith is a powerful and pragmatic solution for scalable Node.js development. It resolves the core issues of structural degradation and hidden dependencies inherent in free-form Node.js development by leveraging a robust plugin system that enforces encapsulation. This pattern ensures maintainability, simplifies testing, and provides a clear, low-friction pathway for future transition to a fully distributed microservices architecture.
Relevant links and hashtags
- Lecture Video: Building a modular monolith with Fastify – Matteo Collina, Node Congress 2023
- Lecturer Professional Links:
- Professional Page: nodeland.dev
- X (Twitter): @matteocollina
- LinkedIn: in/matteocollina
- Organization: Platformatic.dev
Hashtags: #ModularMonolith #Fastify #NodeJSArchitecture #Microservices #SoftwareDesign #OpenSource #NodeCongress