proto-spring-cli
v1.4.0
Published
A command-line tool to quickly set up Spring Boot projects with customizable security, database configurations, and optional validation layers.
Downloads
328
Readme
Spring CLI
A command-line tool to quickly set up Spring Boot projects with customizable security, database configurations, and optional validation layers.
Table of Contents
- Features
- Prerequisites
- Installation
- Usage
- Security Configuration
- Database Configuration
- Database Migration
- Generated Project Structure
- Contributing
- License
Features
- Choose between Spring Security and AWS Cognito for authentication.
- Select from MySQL, MongoDB, PostgreSQL, or SQL Server for the database.
- Automatically generates a
Dockerfile
and GitHub Actions workflows for CI/CD. - Optionally includes a base response structure and validation layers.
- Customizable project details including
groupId
,artifactId
,name
, and more. - Choose between Mongock for MongoDB or Liquibase/Flyway for MySQL, PostgreSQL, and SQL Server database migrations. The CLI automatically configures migrations based on your selections, ensuring initial schema and data setup.
Prerequisites
Ensure the following are installed before using Spring CLI:
- Node.js (version 20.x or higher)
- NPM (version 10.x or higher)
Installation
To install the Spring CLI tool globally via npm, run:
npm install -g proto-spring-cli
Usage
To start the CLI, execute:
proto-spring-cli
Follow the prompts to configure your Spring Boot project as desired.
Options
The CLI will prompt you for the following choices:
- Authentication Choice: Choose between Spring Security and AWS Cognito.
- Database Choice: Select from one of the following:
- MySQL
- MongoDB
- PostgreSQL
- SQL Server
- Project Details:
- Group ID: e.g.,
com.example
- Artifact ID: e.g.,
demo
- Project Name: e.g.,
Demo Project
- Project Description: e.g.,
A Spring Boot demo project
- Package Name: e.g.,
com.example.demo
- Java Version: Choose from Java 17, 21, or 23.
- Group ID: e.g.,
- Additional Configuration Options:
- Include Base Response: Optionally add a base response structure for standardized API responses.
- Add Validation Layer: Optionally include validation logic for your endpoints.
Configuration Requirements
Depending on your choices, some manual configuration will be necessary:
Security Configuration
Spring Security Configuration
If you selected Spring Security, update the application.yml
file with the following settings:
spring:
security:
openPaths:
- /api/auth/**
- /public/**
jwt:
secret-key: It must be at least 256 bits (32 bytes). BASE64 Format
# like cHJvdG8xMjM0NTY3OEFhISFwcm90bzEyMzQ1Njc4QWEhIXByb3RvMTIzNDU2NzhBYSEhcHJvdG8xMjM0NTY3OEFhISE=
expiration-time: 3600000
refresh-expiration-time: 3600000
The secret-key
, expiration-time
, and refresh-expiration-time
values should be customized based on your environment.
AWS Cognito Configuration
If you selected Cognito, update the application.yml
file with the following settings:
aws:
access: <your-access-key>
secret: <your-secret-key>
region: <your-region>
cognito:
userPoolId: <your-user-pool-id>
clientId: <your-client-id>
spring:
security:
openPaths:
- /api/auth/**
- /public/**
oauth2:
resourceserver:
jwt:
issuer-uri: <your-issuer-uri>
jwk-set-uri: <your-jwk-set-uri>
client:
provider:
cognito:
issuer-uri: <your-issuer-uri>
registration:
cognito:
client-id: <your-client-id>
scope: openid
authorization-grant-type: authorization_code
Database Configuration
Update the application.yml file with your chosen database configuration:
MySQL Example
spring:
datasource:
url: jdbc:mysql://localhost:3306/demo_db
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:
ddl-auto: update
properties:
hibernate:
dialect: org.hibernate.dialect.MySQLDialect
format_sql: true
show_sql: true
MongoDB Example
spring:
data:
mongodb:
authentication-database: admin
host: localhost
username: rootuser
password: rootpass
database: demo_db
port: 27017
BaseResponse Configuration
If you chose to include the BaseResponse
structure, you can use it for standardized API responses:
Define the BaseResponse Class
public class BaseResponse<T> {
private boolean success;
private String message;
private T data;
public BaseResponse(boolean success, String message, T data) {
this.success = success;
this.message = message;
this.data = data;
}
// Getters and setters...
}
Use BaseResponse in a Controller Endpoint
@PostMapping("/api/user")
public ResponseEntity<BaseResponse<User>> createUser(@RequestBody User user) {
// Example response
return ResponseEntity.ok(new BaseResponse<>(true, "User created successfully", user));
}
Exception Handling Configuration
If you included the exception handling configuration, create an ExceptionHandler for better error management:
Define an Exception Enum for Error Codes
public enum ErrorCode {
USER_NOT_FOUND("E001", "User not found"),
INVALID_REQUEST("E002", "Invalid request");
private final String code;
private final String message;
ErrorCode(String code, String message) {
this.code = code;
this.message = message;
}
// Getters...
}
Create a Global Exception Handler
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<BaseResponse<Void>> handleUserNotFoundException(UserNotFoundException ex) {
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body(new BaseResponse<>(false, ErrorCode.USER_NOT_FOUND.getMessage(), null));
}
@ExceptionHandler(Exception.class)
public ResponseEntity<BaseResponse<Void>> handleGeneralException(Exception ex) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(new BaseResponse<>(false, "An unexpected error occurred", null));
}
}
Validation Layer
If you included the validation layer, follow these steps:
Create a Validator Class
public class UserControllerValidator extends ControllerValidator {
@ValidationComponent
@RequiredArgsConstructor
public static class CreateUserValidator implements Validator {
@Override
public boolean supports(Class<?> clazz) {
return UserController.class.equals(clazz);
}
@Override
public void validate(Object target, Errors errors) {
MapBindingResult result = (MapBindingResult) errors;
Map<?, ?> params = result.getTargetMap();
UserRequest request = (UserRequest) params.get(REQ_NAME);
if (request.getFirstName() == null) {
reject(result, ValidationExceptionEnum.USER_NAME_CANNOT_BE_NULL);
}
}
}
}
Use the Validator in a Controller Endpoint
@PostMapping
@ProtoValidator(validator = UserControllerValidator.CreateUserValidator.class)
public ResponseEntity<BaseResponse<?>> createUser(@RequestBody UserRequest request) {
return ResponseEntity.ok(new BaseResponse<>("User created successfully"));
}
Database Migration
Update the application.yml
file with your chosen database configuration:
Database Migration Options
This CLI provides automatic database migrations based on the selected database type:
- MongoDB: Uses Mongock to manage migrations. Changlogs and initial data are set up for MongoDB collections.
- MySQL, PostgreSQL, SQL Server: Choose between Liquibase and Flyway. The selected migration tool will manage schema updates and apply initial scripts.
Example application.yml configuration for MySQL with Flyway:
spring:
datasource:
url: jdbc:mysql://localhost:3306/demo_db
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
flyway:
enabled: true
locations: classpath:/db/migration
Generated Project Structure
Once the setup is complete, your project will include:
- A fully configured Spring Boot application.
- Security and database configurations based on your selections.
- Optional validation and base response layers.
- A
Dockerfile
for containerizing your application. - GitHub Actions workflows for continuous integration and deployment.
Commit Message Format
We have very precise rules over how our Git commit messages must be formatted. This format leads to easier to read commit history.
Each commit message consists of a header, a body, and a footer.
<header>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
The header
is mandatory and must conform to the Commit Message Header format.
The body
is mandatory for all commits except for those of type "docs".
When the body is present it must be at least 20 characters long.
The footer
is optional. The Commit Message Footerformat describes what the footer is used for and the structure it must have.
Commit Message Header
<type>(<scope>): <short summary>
│ │ │
│ │ └─⫸ Summary in present tense. Not capitalized. No period at the end.
│ │
│ └─⫸ Commit Scope: <optional>
│
└─⫸ Commit Type: build|ci|docs|feat|fix|perf|refactor|test
The <type>
and <summary>
fields are mandatory, the (<scope>)
field is optional.
Type
Must be one of the following:
build: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
ci: Changes to our CI configuration files and scripts (examples: CircleCi, SauceLabs)
docs: Documentation only changes
feat: A new feature
fix: A bug fix
perf: A code change that improves performance
refactor: A code change that neither fixes a bug nor adds a feature
test: Adding missing tests or correcting existing tests
License
This project is licensed under the MIT License.