Skip to content

lavantien/springboot-restapi

Repository files navigation

Simple RESTful API with Validator and Unit Testing

CI

Includes

  • Utilize Java 20
  • Spring Command Line Runner for migrating players data
  • Handle LocalDate serialize/deserialize
  • Spring Web CRUD
  • Spring Data JPA
  • PostgreSQL
  • Docker Compose
  • Standard Response Codes
  • Combinator Validation
  • Spring Boot Test Starter (Mockito + AssertJ)
  • GitHub Actions CI Pipeline
  • [ ] Exceptions Deprecated
  • [ ] Spring HATEOAS Deprecated

References

Local Setup

With an IDE

  • Install Java 20, latest Docker, and IntelliJ Community with the IdeaVim & Docker plugins installed
  • Run the database by open project with IntelliJ, open compose.yaml and hit run
  • Create player database in a terminal:
docker exec -it postgres bash
psql -U postgres
create database player;
  • Run the backend by open com/lavantien/restapi/RestapiApplication.java

With Neovim

  • Install Java 20, latest Docker, and Neovim with the Mason plugins; Use Mason to install a Java LS
  • Run the database in a terminal:
docker compose up -d
  • Create player database in a terminal:
docker exec -it postgres bash
psql -U postgres
create database player;
  • Run the backend in a terminal:
mvn install
mvn spring-boot:run

Common

  • Run unit test with mvn test, or more specifically ClassName#methodName:
mvn test -Dtest=ControllerTest#allPlayers test
  • Using curl or any mock callers to test the endpoints at localhost:8081
  • Or you can use Kreya and take advantage of the mock-caller directory
  • There will be an existing list of players migrated to the database for testing purpose

API Documentation

  • GET /api/players retrieves a list of all players
[
  {
    "id": 2,
    "name": "player b",
    "email": "[email protected]",
    "password": "password",
    "dateOfBirth": "2023-05-21"
  },
  {
    "id": 3,
    "name": "player c",
    "email": "[email protected]",
    "password": "password",
    "dateOfBirth": "2023-05-21"
  },
  {
    "id": 4,
    "name": "player d",
    "email": "[email protected]",
    "password": "password",
    "dateOfBirth": "2023-05-21"
  }
]
  • GET /api/players/{id} retrieves a specific player with the matching id
{
  "id": 6,
  "name": "player f",
  "email": "[email protected]",
  "password": "password",
  "dateOfBirth": "2023-05-21"
}
  • POST /api/players creates a new player; returned the newly created player
{
  "id": 32,
  "name": "player 0",
  "email": "[email protected]",
  "password": "12345670",
  "dateOfBirth": "1990-02-01"
}
  • PATCH /api/players creates a batch of new players; returned the failed players
[
  {
    "id": 27,
    "name": "player 1",
    "email": "player0gmail.com",
    "password": "12345671",
    "dateOfBirth": "1990-01-01"
  },
  {
    "id": 28,
    "name": "player 1",
    "email": "[email protected]",
    "password": "12345672",
    "dateOfBirth": "2020-01-02"
  }
]
  • PUT /api/players/{id} edits an existing player with the matching id; returned the newly edited player; creates new player if not existed
{
  "id": 6,
  "name": "player 6",
  "email": "[email protected]",
  "password": "12345670",
  "dateOfBirth": "1990-02-01"
}
  • DELETE /api/players/{id} deletes an existing player with the matching id; returned nothing if success

Errors Handling

  • Based on standard HTTP status codes
  • The returned error payload contains the error message relates to the root cause