Skip to content

RESTful API for project collaboration and issue tracking using Spring Boot, Spring MVC, JPA, PostgreSQL, Redis, and JWT

License

Notifications You must be signed in to change notification settings

akorotky/issue-tracker-api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

91 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

About

This repository contains the code for the backend of the full-stack Issue Tracker project.
The frontend code can be found in the following repository.

Technology Stack

  • Languages: Java 19
  • Frameworks: Spring/Spring Boot
  • Build tools: Maven
  • Servers: Tomcat
  • Databases: PostgreSQL, Redis

Dependencies

  • Spring Web
  • Spring Data JPA
  • Spring Security
  • Spring HATEOAS
  • PostgreSQL Driver
  • Spring Boot Dev Tools
  • Spring Validation
  • Lombok
  • Jackson Databind
  • SpringDoc OpenAPI WebMVC UI
  • Mapstruct
  • JJWT
  • Spring Data Redis
  • Jedis
  • Spring Security ACL

API Features

  • RESTful CRUD API
  • Authentication & authorization (JWT)
  • Fine-grained resource access control
  • OpenAPI documentation with Swagger UI playground

API Documentation

You can acess the OpenAPI Specification of the Issue Tracker API in JSON format at http://localhost:8080/v3/api-docs.

You can also download the documentation as a YAML file from http://localhost:8080/v3/api-docs.yaml.

You can explore and play with the Issue Tracker API in an interactive environment generated by Swagger UI at http://localhost:8080/swagger-ui.html.

Installation

1. Prerequisites

You need to have PostgreSQL and Redis servers set up and running in order to run this application.

2. Clone the repository

git clone https://github.com/akorotky/issue-tracker-api.git

3. Enter the project folder

cd issue-tracker-api

4. Customize the application properties

In the application.properties file, put your PostgreSQL credentials. You can also add or remove other properties if you like.

5. Run the application

You can run the application using an IDE of your choice (i.e. IntelliJ), or with the command line mvn spring-boot:run (you need to have Maven installed). The application server will start at http://localhost:8080.

6. Authentization and authorization

Since the application is secured, you need to authenticate first in order to access the API. You can do that using Postman (best experience) or using the Linux curl CLI tool.

A mock user with username user and password password already exists, so you can use these credentials to authenticate. To do that, you need to send a HTTP POST request to http://localhost:8080/api/auth/login with a valid username and password.

Example request:

{
    "username": "user",
    "password": "password"
}

Example response:

{
    "accessToken": "eyJhbGciOiJFUzI1NiJ9.eyJzdWIiOiJ1c2VyIiwiYXV0aG9yaXRpZXMiOlsiVVNFUiJdLCJpYXQiOjE2ODQ0NjM5MzQsImV4cCI6MTY4NDQ2NDgzNH0.LLkEf3QfkYWr_gOxt4jwCTg5leXqy85BMb5VqrIfJS0ma2RqZVyfaGE3Tlckt5CdKRTSdvUv3eUeMWlrjDwspA",
    "refreshToken": "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c2VyIiwiYXV0aG9yaXRpZXMiOlsiVVNFUiJdLCJpYXQiOjE2ODQ0NjM5MzQsImV4cCI6MTY4NTA2ODczNH0.qfttGoaNLTaG17OGIncP5S3_D9sGLvaw6pDwCtlDY8oqQULuGKm3FH7xHIZjkTUjOZP71xXWXAIXCkw94x_mNIAt5uK59_ZnY-vce5sj03C0VGQBHfIzZsfk_di9K8uH7rd6HckGizl_vG4kUgUpnmzER5qN97G0_D-7f1kRToyO1ud6_X7phd7bN1PCqJBdBYm4KcV3lP3_gVmNvV-upahTSlR5XTYX4DZu828DGVemYZed72UN7kazvd4pXwQ1wwcR9T7JEo3pexZpoYB5Mnhgq1hW6iWEbX9P6RoOHQOIafOy1E9lF76Jh_nMCe65cAw-a7ErZsHg-aLn3V4vGw"
}

Example using curl: curl -X POST -H http://localhost:8080/api/auth/login "Content-Type: application/json" -d '"username":"user", "password":"password"'

Access token is a short-lived Json Web Token (the token is valid only for 15 minutes) that you can put into the HTTP Authorization header when accessing the API, in order to avoid always sending username and password on every request. When the access token expires, you can use the refresh token (valid for 1 week) to generate a new access token by sending a POST request to the http://localhost:8080/api/auth/token endpoint with the refresh token in the request body.

REST API

Auth API

HTTP Method URI Description
POST /api/auth/login Sign in
POST /api/auth/token Create and get an access + refresh token pair

User API

HTTP Method URI Description
GET /api/users Get all users
POST /api/users Create/register a user
GET /api/users/{username} Get user data
PATCH /api/users/{username} Update user data
DELETE /api/users/{username} Delete user

Project API

HTTP Method URI Description
GET /api/projects Get all projects
GET /api/projects?user={username} Get all projects where user is the owner
GET /api/projects?collaborator={username} Get all projects where user is a collaborator
POST /api/projects Create a project
GET /api/projects/{projectId} Get project data
PATCH /api/projects/{projectId} Update project data
DELETE /api/projects/{projectId} Delete project
DELETE /api/projects/{projectId}/issues Get project issues
GET /api/projects/{projectId}/collaborators Get project collaborators
PUT /api/projects/{projectId}/collaborators/{username} Add a project collaborator
DELETE /api/projects/{projectId}/collaborators/{username} Delete project collaborator

Issue API

HTTP Method URI Description
GET /api/issues Get all issues
POST /api/issues Create an issue
GET /api/issues/{issueId} Get issue data
PATCH /api/issues/{issueId} Update issue
DELETE /api/issues/{issueId} Delete issue
GET /api/issues/{issueId}/comments Get issue comments

Comment API

HTTP Method URI Description
GET /api/comments Get all comments
POST /api/comments Create a comment
GET /api/comments/{commentId} Get comment data
PATCH /api/comments/{commentId} Update comment
DELETE /api/comments/{commentId} Delete comment

RESTful Request/Response Example:

Request:

A GET request to http://localhost:8080/api/projects/1 returns the project with an id of 1:

Response:

{
    "id": 1,
    "title": "Issue Tracker API",
    "description": "RESTful API for project collaboration and issue tracking."
    "private": false,
    "owner": {
        "id": 1,
        "username": "user",
        "email": "user@issuetracker.test",
        "roles": [
            "USER"
        ]
    },
    "_links": {
        "self": {
            "href": "http://localhost:8080/api/projects/1"
        },
        "owner": {
            "href": "http://localhost:8080/api/users/user"
        },
        "collaborators": {
            "href": "http://localhost:8080/api/projects/1/collaborators"
        },
        "issues": {
            "href": "http://localhost:8080/api/projects/1/issues"
        }
    }
}