{"id":25422370,"url":"https://github.com/lavantien/springboot-restapi","last_synced_at":"2026-05-02T08:35:13.849Z","repository":{"id":167279226,"uuid":"642866492","full_name":"lavantien/springboot-restapi","owner":"lavantien","description":"A simple RESTful API with Validator and Unit Testing","archived":false,"fork":false,"pushed_at":"2026-02-28T08:18:31.000Z","size":140,"stargazers_count":4,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-28T14:02:45.201Z","etag":null,"topics":["ci-pipeline","docker-compose","functional-programming","java","rest-api","spring-boot","unit-testing"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lavantien.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2023-05-19T14:18:44.000Z","updated_at":"2026-02-28T08:18:35.000Z","dependencies_parsed_at":null,"dependency_job_id":"ca026aea-940b-4993-b4be-04ecf594568c","html_url":"https://github.com/lavantien/springboot-restapi","commit_stats":null,"previous_names":["lavantien/springboot-restapi"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/lavantien/springboot-restapi","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lavantien%2Fspringboot-restapi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lavantien%2Fspringboot-restapi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lavantien%2Fspringboot-restapi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lavantien%2Fspringboot-restapi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lavantien","download_url":"https://codeload.github.com/lavantien/springboot-restapi/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lavantien%2Fspringboot-restapi/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32528438,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-02T01:12:54.858Z","status":"online","status_checked_at":"2026-05-02T02:00:05.923Z","response_time":132,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["ci-pipeline","docker-compose","functional-programming","java","rest-api","spring-boot","unit-testing"],"created_at":"2025-02-16T21:32:52.323Z","updated_at":"2026-05-02T08:35:13.833Z","avatar_url":"https://github.com/lavantien.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Simple RESTful API with Validator and Unit Testing\n\n![CI](https://github.com/lavantien/springboot-restapi/actions/workflows/ci.yml/badge.svg)\n\n## Includes\n\n- [x] Utilize Java 20\n- [x] Spring Command Line Runner for migrating players data\n- [x] Handle LocalDate serialize/deserialize\n- [x] Spring Web CRUD\n- [x] Spring Data JPA\n- [x] PostgreSQL\n- [x] Docker Compose\n- [x] Standard Response Codes\n- [x] Combinator Validation\n- [x] Spring Boot Test Starter (Mockito + AssertJ)\n- [x] GitHub Actions CI Pipeline\n- ~~[ ] Exceptions~~ Deprecated\n- ~~[ ] Spring HATEOAS~~ Deprecated\n\n## References\n\n- [Java Versions and Features](https://www.marcobehler.com/guides/a-guide-to-java-versions-and-features)\n- [Building REST services with Spring](https://spring.io/guides/tutorials/rest/)\n- [Cross Site Request Forgery (CSRF)](https://docs.spring.io/spring-security/reference/servlet/exploits/csrf.html#servlet-csrf-configure-disable)\n- [Unit Testing with Spring Boot](https://reflectoring.io/unit-testing-spring-boot/)\n- [Setup Postgres in GitHub Actions](https://remarkablemark.org/blog/2021/03/14/setup-postgresql-in-github-actions/)\n- [Adding workflow status badge](https://docs.github.com/en/actions/monitoring-and-troubleshooting-workflows/adding-a-workflow-status-badge)\n- [Learn Spring Boot 3](https://youtu.be/-mwpoE0x0JQ)\n- [Java Functional Programming](https://youtu.be/VRpHdSFWGPs)\n\n## Local Setup\n\n### With an IDE\n\n- Install `Java 20`, latest `Docker`, and `IntelliJ Community`\n  with the `IdeaVim` \u0026 `Docker` plugins installed\n- Run the database by open project with IntelliJ, open `compose.yaml` and hit run\n- Create `player` database in a terminal:\n\n```bash\ndocker exec -it postgres bash\npsql -U postgres\ncreate database player;\n```\n\n- Run the backend by open `com/lavantien/restapi/RestapiApplication.java`\n\n### With Neovim\n\n- Install `Java 20`, latest `Docker`, and `Neovim` with the `Mason` plugins;\n  Use `Mason` to install a Java LS\n- Run the database in a terminal:\n\n```bash\ndocker compose up -d\n```\n\n- Create `player` database in a terminal:\n\n```bash\ndocker exec -it postgres bash\npsql -U postgres\ncreate database player;\n```\n\n- Run the backend in a terminal:\n\n```bash\nmvn install\nmvn spring-boot:run\n```\n\n### Common\n\n- Run unit test with `mvn test`, or more specifically `ClassName#methodName`:\n\n```bash\nmvn test -Dtest=ControllerTest#allPlayers test\n```\n\n- Using `curl` or any mock callers to test the endpoints at `localhost:8081`\n- Or you can use `Kreya` and take advantage of the `mock-caller` directory\n- There will be an existing list of players migrated to the database\n  for testing purpose\n\n## API Documentation\n\n- `GET /api/players` retrieves a list of all players\n\n```json\n[\n  {\n    \"id\": 2,\n    \"name\": \"player b\",\n    \"email\": \"b@b.com\",\n    \"password\": \"password\",\n    \"dateOfBirth\": \"2023-05-21\"\n  },\n  {\n    \"id\": 3,\n    \"name\": \"player c\",\n    \"email\": \"c@c.com\",\n    \"password\": \"password\",\n    \"dateOfBirth\": \"2023-05-21\"\n  },\n  {\n    \"id\": 4,\n    \"name\": \"player d\",\n    \"email\": \"d@d.com\",\n    \"password\": \"password\",\n    \"dateOfBirth\": \"2023-05-21\"\n  }\n]\n```\n\n- `GET /api/players/{id}` retrieves a specific player with the matching `id`\n\n```json\n{\n  \"id\": 6,\n  \"name\": \"player f\",\n  \"email\": \"f@f.com\",\n  \"password\": \"password\",\n  \"dateOfBirth\": \"2023-05-21\"\n}\n```\n\n- `POST /api/players` creates a new player; returned the newly created player\n\n```json\n{\n  \"id\": 32,\n  \"name\": \"player 0\",\n  \"email\": \"player0@gmail.com\",\n  \"password\": \"12345670\",\n  \"dateOfBirth\": \"1990-02-01\"\n}\n```\n\n- `PATCH /api/players` creates a batch of new players;\n  returned the failed players\n\n```json\n[\n  {\n    \"id\": 27,\n    \"name\": \"player 1\",\n    \"email\": \"player0gmail.com\",\n    \"password\": \"12345671\",\n    \"dateOfBirth\": \"1990-01-01\"\n  },\n  {\n    \"id\": 28,\n    \"name\": \"player 1\",\n    \"email\": \"player1@gmail.com\",\n    \"password\": \"12345672\",\n    \"dateOfBirth\": \"2020-01-02\"\n  }\n]\n```\n\n- `PUT /api/players/{id}` edits an existing player with the matching `id`;\n  returned the newly edited player; creates new player if not existed\n\n```json\n{\n  \"id\": 6,\n  \"name\": \"player 6\",\n  \"email\": \"player6@gmail.com\",\n  \"password\": \"12345670\",\n  \"dateOfBirth\": \"1990-02-01\"\n}\n```\n\n- `DELETE /api/players/{id}` deletes an existing player with the matching `id`;\n  returned nothing if success\n\n```json\n\n```\n\n## Errors Handling\n\n- Based on standard HTTP status codes\n- The returned error payload contains the error message relates to the root cause\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flavantien%2Fspringboot-restapi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flavantien%2Fspringboot-restapi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flavantien%2Fspringboot-restapi/lists"}