joeclark-phd / granite

A model or starter for a Java web application that will be highly-maintainable over a long period of time (20+ years)
0 stars 2 forks source link
java maintainable spring-boot starter web-app

Build Status Codacy Badge DepShield Badge

granite

This project is intended to be a model or starter for a Java web application that will be highly-maintainable over a long period of time (20+ years).

business requirements

goals

A web application that lives a long time will be touched by a lot of people. It will see numerous version changes in programming languages, databases, etc., and will sometimes have to make those changes urgently due to security vulnerabilities. It should avoid unnecessary complexity that will make it harder for later developers to orient themselves. It should have a solid logging framework, automated testing, security, accessibility, instrumentation (e.g. for performance analytics), and documentation from the very beginning. That's a lot of up-front work before really developing the app's functionality, but it will lead to a profound reduction of risk and cost in years to come. This repo will allow that up-front work to be re-usable for more than one project.

It should have a build process defined in code (i.e. Maven) and an environment defined in code (i.e. Docker) so that these will be communicated and kept up to date via version control. The build process should be independent of a developer's IDE (or really anything outside the version-controlled code repo). Differences in environments should be kept out of the code, so the same application can run in all environments. (I am used to using environment variables for this, but my impression is that the Java world prefers XML configuration files. I'll research further before choosing an approach.) The application should rely on external libraries as much as possible, to keep its own codebase small. Specified version numbers of these libraries should be pulled in with a dependency manager rather than bundled with the project. This prevents the evolution of modified/customized libraries over the years. Additionally, version numbers can sometimes be hard to figure out from an old JAR or an old script, so the dependency manifest (i.e. pom.xml) makes them clear for all time. As a corollary, we should try to pick libraries that are in broad use and will likely still exist for years to come.

The DDL script(s) that define the database(s) should also be version-controlled, even if the database is not part of the automated build process, both to maintain the history of changes and so they can be used to generate mock databases during automated testing. I assume that developers will not have direct control of their production database, but will be working with a DBA. They need to be able to design a migration (DDL script to alter or add to the schema), re-build a mock database on their local machine and/or test server, and then hand it to the DBA. If building a mock database is part of the automated build/test cycle it should quickly alert the the team to database changes that don't get recorded in the code repository, and vice versa.

Since code updates may be "out of sync" with database changes, some effort should be made to ensure backward and forward compatibility (see Ambler & Sadalage's Refactoring Databases: Evolutionary Database Design for some ideas). For starters:

design principles

technologies

build process

The Maven build process:

To try it out for yourself, from this directory try mvn clean test.

Try it out

You can build the application and run main() in Application.java using an IDE, with --spring.profiles.active=dev and a database already running as defined in application-dev.yml.

Alternatively, you can use Docker to spin up both a test database and an instance of the app. See my Docker README for instructions.

Then check out the web app running at http://localhost:8080. The test user account is joe and the password is test.