Skip to content

Backend Core

backend-core is a set of common interfaces and implementations that supports the principles of a clean, layered architectural design for enterprise applications. It provides the reusable building blocks — base classes, mixin interfaces, and contracts — that are typically rewritten from scratch on every new enterprise project.

Canonical source

Most of the content in this section is derived from the design document published at backend-core/src/site/markdown/index.md in the project repository. It has been re-edited for clarity and split across several pages for navigability.

Introduction

Building enterprise applications usually means stacking three kinds of frameworks: a presentation framework, a persistence framework, and a dependency-injection framework that glues the layers together. Within that stack, the typical CRUD features look remarkably similar from one project to the next — and a lot of the back-end code (everything outside the presentation layer) can be reused.

The motivation for Backend Core is to capture that reusable code in one place. With modern Java — default methods on interfaces, lambdas, method references — common base classes and contracts can be expressed as composable interfaces instead of inheritance-only hierarchies, which keeps the library lightweight and lets you opt in to the parts you need.

Scope

Backend Core focuses on the following use cases:

Code reuse for CRUD functionalities

The library provides base classes and interfaces that reduce the boilerplate needed to build a typical CRUD feature.

A CRUD functionality is a visual feature that lets a user Create an instance of a persistent entity (with input validation), Read a previously persisted entity by search/query/list with filtering, Update the state of a persisted entity, and Delete it from the persistent storage.

Persistent storage

For enterprise applications the persistent storage is most often a relational database. Backend Core is designed primarily for that case, but it provides a base that can be adapted to other storage types (NoSQL, remote APIs).

It relies on JPA — a mature standard that abstracts over multiple persistence providers — so consumers are not coupled to any specific provider (Hibernate, EclipseLink, etc.). When a design trade-off forces a choice between relational and non-relational support, relational support takes priority.

Queries and filtering

Filtering persisted entities is one of the hardest things to write well in an enterprise application. The naive approach — passing each optional attribute as a separate parameter down through the layers, then assembling the query manually — has several problems:

  • It only scales for a small number of parameters. Past that, you need a class to carry them.
  • That class becomes an implicit projection of the persistent entity. If the entity changes (for example, two attributes are merged into a fullName), there is no compiler-enforced link between the entity and its filter class, so the change is silently missed.
  • Tools like Lombok can generate constant fields for attribute names so changes surface as compilation errors, but they still don't carry type information.

Backend Core provides a filtering feature that you can opt into, designed to reduce this boilerplate while keeping a strongly-typed approach.

Non-functional requirements

Java version

The library targets Java 8 as the minimum supported version, making heavy use of Java 8 language features (default methods, lambdas, method references). Newer Java versions are welcome, but Java 8 must always be supported.

Class hierarchy

Class hierarchy is treated as a feature that consumers opt into. Before default methods on interfaces, libraries like this typically forced consumers to extend a base class to get its behavior. With default methods, the same behavior can be exposed as an interface — letting consumers manage their own class hierarchy and pick features by implementing the relevant interfaces.

Architecture design patterns

The most important pattern Backend Core targets is the three-tier architecture with strict separation of layers, meaning each layer can be packaged in its own module without leaking framework dependencies to the others:

  • No persistence-specific framework or library should be required in the business-logic layer.
  • No business-logic-specific framework or library should be required to call business services from the presentation layer.

The library provides interfaces that serve as the foundation for those contracts. It is also possible to build applications that do not need this strict separation — see Architecture for the supported approaches.

Strict separation is also a good fit for Domain-Driven Design and hexagonal architectures. Supporting them is a desirable outcome but not a priority.

What's next

  • Architecture — the layer model and the supported separation approaches.
  • Modules — what each Maven module of Backend Core provides.
  • Getting Started — coordinates, snapshot repository, and how to build from source.

Source

Source code: backend-core on GitHub. Released under the Apache License 2.0.