Skip to main content

Command Palette

Search for a command to run...

SpringForge Dev Diary: How We’re Automating Spring Boot CRUD with Models

Exploring the inspiration and lessons behind SpringForge — my model-driven tool for generating Spring CRUD logic.

Updated
6 min read
SpringForge Dev Diary: How We’re Automating Spring Boot CRUD with Models

Hey everyone! Welcome to my next blog post. Today, I’m excited to share details about my app, SpringForge, a model-driven Spring CRUD application generator that I’ve led the development of. In this blog post, let’s explore my inspiration for the project, its features, how my partner and I built it, challenges we’ve had, and some takeaways for your own future projects.

Project Inspiration

After my project, Quak Framework, a Spring Framework clone with some of my own twists on things, I reflected a lot on the potential impact of the project. One thing that bothered me was that I felt like I couldn’t make a significant impact with Quak since it was unrealistic for me to create a viable alternative to Spring. Instead, I wanted to build something that could be a useful tool for Spring developers, which seemed like a more approachable angle to build something with greater impact.

The Eureka

I was considering the code-generation aspect of Quak Framework and thought of doing something similar, more sophisticated, and for the Spring Framework instead. The initial idea was to build a CLI tool (similar to the Angular CLI) for generating Spring CRUD logic (pretty close to the final idea). However, a few things caused me to pivot on that idea:

  1. It’s been a while since I’ve worked with Angular, and I wanted to build something nice to refresh on it and show on my portfolio.

  2. I recently took a software engineering course in the final year of my undergraduate degree, and was fascinated by the idea of model-driven engineering, which was brought up.

  3. A couple of years ago, I worked on a school project involving editing graphs on a web page, and thought I could reuse some of that experience.

That's when I got my final idea for SpringForge: create an editor for ER-like diagrams, serialize it as JSON for a backend, and generate Spring CRUD apps from it!

Introducing SpringForge 🚀

From that eureka, my idea for SpringForge was born. In the initial release, the app featured:

🧠 Smart code generation for entities, DTOs, JPA repositories, and REST controllers;

🤖 AI-powered unit test generation;

🖼️ and a polished and intuitive UI.

Through that, I hope to automate some of the annoying boilerplate of coding CRUD application logic with Spring.

Tools & Tech Stack

To build the application, we used the following tech stack and tools:

Backend

  • Spring Framework for implementing the backend endpoints

  • Firebase for user authentication, NoSQL document-based database storage, and file storage buckets

  • JavaPoet for code generation

Frontend

  • Angular for implementing the frontend logic and UI

Deployment

  • Heroku for the backend deployment platform

  • Docker for easier deployment setup on Heroku

  • Firebase for the frontend deployment

CI

  • GitHub actions for running our CI pipelines

  • Codecov for managing code coverage reports and displaying them within GitHub

Challenges

While the four months of development for the initial release have been a fun experience, it wasn't without major challenges. I thought I'd share two of the major ones so you can avoid some of the mistakes I’ve made and learn from what went well here.

Unit Testing

One of the biggest challenges of building this project was unit testing the code generation functionality. While I was able to achieve around 80% backend code coverage, I think I could have made some of the tests more useful than they were. A good portion of the assertions involve creating expected TypeSpec instances with JavaPoet using repeated logic as the code itself. In the future, I'd like to refactor these tests to something more useful, like asserting a string with the expected code instead. As time went by, however, I would say I wrote some better tests with this improvement in mind.

Outside of the backend tests for code generation, I also wrote tests for components using the Firebase Admin API. These posed their own unique challenges of a complex mock setup to avoid actually invoking Firebase. This involved using static mocking for singleton calls, setting up a ton of mocks for chained calls involving collections, documents, and data snapshots, and verifying method calls were made on those mocks. While this was often tedious and complicated, I'm really happy with how those tests turned out.

Lastly, for frontend unit testing, the biggest regret was not writing frontend tests sooner. Here, I was a little eager working on the frontend, not too experienced with frontend testing, and intimidated by the thought of writing frontend tests for this, so I put it off for a lot longer than I should have. After a while, I decided to take a big leap at adding unit tests, realizing that it wasn't as complex as I thought and that I should take the correctness of the frontend more seriously. While I made good progress on that, the frontend code coverage is still not ideal, and if I had started sooner (i.e., with test-driven development or at least loosely following it), it would be a lot better.

UI Development

One of the biggest challenges that Elli, my UI/UX designer and frontend developer, faced was working with the Angular Material UI library. Initially, I had built prototypes for the UI using this library because of my prior experience with it and its relative simplicity. However, when she started refining the UI and customizing it, she came across challenges working with it. Angular Material, while fairly easy to use for pretty components out of the box, can be fairly hard to customize at times, and the documentation has its own problems. In hindsight, it might have been better if we explored our options first when it came to ready-made components to avoid difficulties like these.

Biggest Takeaways

Finally, I'd like to share the biggest takeaways from this project that you can use to bring your future ideas to life:

1. Build Something That Pushes Your Skills

One thing I always strive for when developing a project idea is to choose something that can further develop my skills. Whether it’s by choosing technologies you want experience with or pushing for something more ambitious than ever, always try to build something that will grow you as a developer, not necessarily something you already know you can build.

2. Inspiration Can Come From Anywhere

As I touched on in the section about my inspiration for the project, you can find inspiration from many places. By reflecting hard on what interests you, what you've done previously, and what you can do to make an impact, you can come up with some awesome ideas for your next project, too.

3. Try to Code More With The Future In Mind

Some of the major mistakes I've made in this project came from just committing to the first solution that came to mind and not stopping to evaluate or improve things first. Had I taken the extra effort in the short term, I could have potentially saved myself from technical debt, future headaches, and wasted time.

What’s Next For SpringForge

While I haven’t touched the project in quite some time, I can promise that changes will come this year. As of now, I’ve already put some major work forward for:

  1. Refactoring the backend to a microservice architecture (more on that soon)

  2. Support for request validation constraints

  3. A new AI-related feature

Conclusion

With that, I hope that gave you good insight into my project, inspired you on your project journey, and gave you some knowledge to consider in your current or future side projects. If you want to try my application for yourself, you can find it at www.springforgeapp.com. Happy coding!