{"id":29354238,"url":"https://github.com/alexdevzz/spring-hex-student-backend","last_synced_at":"2026-05-08T05:08:17.213Z","repository":{"id":303476963,"uuid":"1014502862","full_name":"alexdevzz/spring-hex-student-backend","owner":"alexdevzz","description":"RESTful API backend for student management developed with Spring Boot and Hexagonal Architecture.","archived":false,"fork":false,"pushed_at":"2025-07-07T21:54:16.000Z","size":22,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-07T22:38:27.399Z","etag":null,"topics":["api-versioning","controller-advice","custom-exceptions","docker-compose","dto","error-catalogs","exception-handling","hexagonal-architecture","hibernate","jakarta-validation","java","jpa","lombok","mapper","mapstruct","maven","ports-and-adapters","postgresql","restful-api","sprign-boot"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alexdevzz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-05T21:17:02.000Z","updated_at":"2025-07-07T21:54:19.000Z","dependencies_parsed_at":"2025-07-07T22:39:23.582Z","dependency_job_id":"078dfe62-bf09-429e-8c9c-91fa386d54fa","html_url":"https://github.com/alexdevzz/spring-hex-student-backend","commit_stats":null,"previous_names":["alexdevzz/spring-hex-student-backend"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/alexdevzz/spring-hex-student-backend","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexdevzz%2Fspring-hex-student-backend","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexdevzz%2Fspring-hex-student-backend/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexdevzz%2Fspring-hex-student-backend/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexdevzz%2Fspring-hex-student-backend/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alexdevzz","download_url":"https://codeload.github.com/alexdevzz/spring-hex-student-backend/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexdevzz%2Fspring-hex-student-backend/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264384390,"owners_count":23599612,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-versioning","controller-advice","custom-exceptions","docker-compose","dto","error-catalogs","exception-handling","hexagonal-architecture","hibernate","jakarta-validation","java","jpa","lombok","mapper","mapstruct","maven","ports-and-adapters","postgresql","restful-api","sprign-boot"],"created_at":"2025-07-09T03:11:49.869Z","updated_at":"2026-05-08T05:08:17.154Z","avatar_url":"https://github.com/alexdevzz.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n![Screenshot 2025-07-07 165320](https://github.com/user-attachments/assets/f3958398-97e7-43d5-b181-1ebbb3fe7b31)\n\n\n# Student RESTful API (Hexagonal Architecture) \u003cimg src=\"https://github.com/user-attachments/assets/85abb686-eebf-4dce-aebb-1e833ea9d0df\" alt=\"React\" width=\"30\" height=\"30\"\u003e\n\n[![Java](https://img.shields.io/badge/Java-21-orange.svg)](https://www.oracle.com/java/)\n[![Spring Boot](https://img.shields.io/badge/Spring_Boot-3.5.3-green.svg)](https://spring.io/projects/spring-boot)\n[![PostgreSQL](https://img.shields.io/badge/PostgreSQL-14-blue.svg)](https://www.postgresql.org/)\n![GitHub License](https://img.shields.io/github/license/alexdevzz/spring-hex-student-backend)\n![GitHub Created At](https://img.shields.io/github/created-at/alexdevzz/spring-hex-student-backend)\n[![Arquitectura Hexagonal](https://img.shields.io/badge/Architecture-Hexagonal-9cf)](https://alistair.cockburn.us/hexagonal-architecture/)\n\nRESTful API backend for student management developed with Spring Boot and Hexagonal Architecture. It implements CRUD operations with a focus on maintainability, scalability, clean code, and best practices.\n\n## 🌟 Main Features\n- **Hexagonal Architecture** with clear separation of responsibilities\n- **DTOs** for requests and responses\n- **Centralized error handling** with custom exceptions, controller advisor, error catalog and use of a specific model for error normalization\n- **Endpoint-independent versioning** via HTTP method\n- **Automated mapping** between entities and DTOs\n- **Robust validation** of input data\n\n## 🧩 Project Structure\n\n```\nsrc/\n├── main/\n│   ├── java/\n│   │   └── com/\n│   │       └── backend.student.app/\n│   │           ├── application/                                        ➤ Application (Use Cases and Ports)\n│   │           │   ├── ports/\n│   │           │   │   ├── input                                       ➤ Input Ports (Service Port)\n│   │           │   │   └── output                                      ➤ Output Ports (Persistence Port)\n│   │           │   └── usecase/                                        ➤ Interactors (Use Cases)\n│   │           ├── domain/                                             ➤ Core - Domain\n│   │           │   ├── model/                                          ➤ Models\n│   │           │   └── exception/                                      ➤ Custom Exceptions\n│   │           ├── infrastructure/                                     ➤ Infrastructure (Adapters)\n│   │           │   └── adapters/\n│   │           │       ├── input/                                      ➤ Input Adapters\n│   │           │       │   └── rest/\n│   │           │       │       ├── dto/                                ➤ Data Transfer Obejects\n│   │           │       │       │   ├── request/\n│   │           │       │       │   └── response/ \n│   │           │       │       ├── mapper/                             ➤ Mappers DTO \u003c-\u003e Model\n│   │           │       │       ├── GlobalControllerAdviser.java        ➤ Error Handler\n│   │           │       │       └── StudentRestController.java          ➤ REST Controller\n│   │           │       └── output/                                     ➤ Output Adapters\n│   │           │           └── database/\n│   │           │               └── postgres/\n│   │           │                   ├── entity/                         ➤ Database Entities\n│   │           │                   ├── mapper/                         ➤ Mappers Entity \u003c-\u003e Model\n│   │           │                   ├── repository/                     ➤ JPA - Hibernate\n│   │           │                   └── StudentPersistenceAdapter/      ➤ Persistence Adapter\n│   │           └── utils/\n│   │           │   └── ErrorCatalog.java                               ➤ Error Catalog\n│   │           └── StudentApplication.java                             ➤ Spring Boot Main Run File\n│   └── resources/\n│       └── application.yml                                             ➤ Configurations\n└── test/                                                               ➤ Tests\ndocker-compose.yml                                                      ➤ Docker Compose File\n```\n\n## ⚙️ Technologies Used\n- **Core**: Java 21, Spring Boot 3.5.3\n- **Architecture**: Hexagonal (Ports \u0026 Adapters)\n- **Persistence**: Spring Data JPA, Hibernate, PostgreSQL\n- **Anotation**: Lombok\n- **Mapping**: MapStruct\n- **Validation**: Jakarta Validation\n- **Dependency Management**: Maven\n- **Container Platform**: Docker\n\n## 🛠️ Setup and Installation\n1. **Requirements**:\n   - Java 21\n   - PostgreSQL 14+\n   - Maven 3.8+\n   - Docker 4.42+\n\n2. **Clone repository**:\n   ```bash\n   git clone https://github.com/alexdevzz/spring-hex-student-backend.git\n   cd spring-hex-student-backend\n   ```\n   \n3. **Configure database** (application.yml):\n   ```yaml\n   spring:\n     datasource:\n       url: jdbc:postgresql://localhost:5432/your-db\n       username: your-user\n       password: your-pass\n       driver-class-name: org.postgresql.Driver\n     jpa:\n       hibernate:\n         ddl-auto: update\n   ```\n\n4. **Run**:\n   ```bash\n   mvn spring-boot:run\n   ```\n\n## 🚀 Endpoints (v1)\n| Method | Endpoint                | Description                  |\n|--------|-------------------------|------------------------------|\n| POST   | `students/v1/api/`      | Create new student           |\n| GET    | `students/v1/api/{id}`  | Get student by ID            |\n| GET    | `students/v1/api/`      | List all students            |\n| PUT    | `students/v1/api/{id}`  | Update student               |\n| DELETE | `students/v1/api/{id}`  | Delete student               |\n\n## ✅ Good Practices Implemented\n\n### 1. Error Handling\n```java\n@RestControllerAdvice\npublic class GlobalControllerAdviser {\n\n    @ResponseStatus(HttpStatus.NOT_FOUND)\n    @ExceptionHandler(StudentNotFoundException.class)            // com.backend.student.app.domain.exception.StudentNotFoundException\n    public ErrorResponse handleStudentNotFoundException() {      // com.backend.student.app.domain.model.ErrorResponse\n        return ErrorResponse.builder()\n                .code(STUDENT_NOT_FOUND.getCode())               // com.backend.student.app.utils.ErrorCatalog.STUDENT_NOT_FOUND\n                .message(STUDENT_NOT_FOUND.getMessage())         // com.backend.student.app.utils.ErrorCatalog.STUDENT_NOT_FOUND\n                .timestamp(LocalDateTime.now())\n                .build();\n    }\n\n   // More handlers ...\n}\n```\n\n### 2. DTOs y Mappers\n```java\n@Builder @Getter @Setter\n@AllArgsConstructor @NoArgsConstructor\npublic class StudentCreateRequest {\n    @NotBlank(message = \"Field firt_name cannot be empty or null\")\n    private String firstName;\n    @NotBlank(message = \"Field last_name cannot be empty or null\")\n    private String lastName;\n    @NotBlank(message = \"Field address cannot be empty or null\")\n    private String address;\n    @NotNull(message = \"Flied age cannot be null\")\n    private Integer Age;\n\n}\n\n@Mapper(componentModel = \"spring\")                  // using Mapstruct ...\npublic interface StudentRestMapper {\n    @Mapping(target = \"id\", ignore = true)\n    Student toStudent(StudentCreateRequest request);\n    StudentResponse toStudentResponse(Student student);\n    List\u003cStudentResponse\u003e toStudentResponseList(List\u003cStudent\u003e studentList);\n}\n```\n\n### 3. Hexagonal Architecture\n```java\n// Port\npublic interface StudentPersistencePort {\n    Optional\u003cStudent\u003e findById(Long id);\n    List\u003cStudent\u003e findAll();\n    Student save(Student student);\n    void deleteById(Long id);\n}\n\n// Adapter\n@Component\n@RequiredArgsConstructor\npublic class StudentPersistenceAdapter implements StudentPersistencePort {\n\n    private final StudentJpaRepository studentJpaRepository;\n    private final StudentPersistenceMapper studentPersistenceMapper;\n\n    @Override\n    public Optional\u003cStudent\u003e findById(Long id) {\n        return studentJpaRepository.findById(id)\n                .map(studentPersistenceMapper::ToStudent);\n    }\n\n   // More methods implementations ....\n}\n```\n\n### 4. API Versioning\n```java\n@RestController\n@RequestMapping(\"/students\")\n@RequiredArgsConstructor\npublic class StudentRestController {\n\n    private final StudentServicePort servicePort;\n    private final StudentRestMapper restMapper;\n\n   // ...\n\n    @GetMapping(\"/v1/api/{id}\")\n    public StudentResponse findById(@PathVariable Long id) {\n        return restMapper.toStudentResponse(servicePort.findStudentById(id));\n    }\n\n    @PostMapping(\"/v1/api\")\n    public ResponseEntity\u003cStudentResponse\u003e create(@Valid @RequestBody StudentCreateRequest request) {\n        return ResponseEntity.status(HttpStatus.CREATED)\n                .body(restMapper.toStudentResponse(servicePort.createStudent(restMapper.toStudent(request))));\n    }\n\n   // ...\n}\n```\n\n## 📊 Database Model\n```mermaid\nerDiagram\n    STUDENT {\n        Long id PK\n        String first_name\n        String last_name\n        String address\n        String Age\n    }\n```\n\n## 📦 Deployment with Docker Compose\n```bash\ndocker-compose up -d\n```\n\nDocker Compose Configuration:\n```yaml\nservices:\n  postgres:\n    image: postgres:14.18-bookworm\n    container_name: postgres_spring_student_backend_container\n    environment:\n      POSTGRES_USER: your-user\n      POSTGRES_PASSWORD: your-pass\n      POSTGRES_DB: your-db\n    ports:\n      - \"5432:5432\"\n    volumes:\n      - postgres_data:/var/lib/postgresql/data\n    restart: unless-stopped\n\nvolumes:\n  postgres_data:\n```\n\n## 🤝 Contributions\n1. Fork the project\n2. Create your feature branch (`git checkout -b feature/new-feature`)\n3. Commit your changes (`git commit -am 'Add new feature'`)\n4. Push to the bransh (`git push origin feature/new-feature`)\n5. Open a Pull Request\n\n## 📄 License\nDistributed under the MIT License. See `LICENSE` for more information.\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexdevzz%2Fspring-hex-student-backend","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexdevzz%2Fspring-hex-student-backend","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexdevzz%2Fspring-hex-student-backend/lists"}