This project is implemented using the Spring Boot framework for building RESTful APIs. We have chosen PostgreSQL as the database to store data.
Authentication is implemented using Spring boot JWT Authentication. A token is generated as soon as a user execute login api which can be used to access other apis. The token gets expired after a particular time.
The RateLimiter class utilizes a ConcurrentHashMap to store request counts for each client. It ensures thread safety during concurrent access.
MAX_REQUESTS: Defines the maximum allowed requests per time window.
TIME_WINDOW_SECONDS: Specifies the duration of the time window in seconds.
The requestCounts map stores the last request time for each client and their corresponding request count. Request Handling:
On each incoming request, the system checks the elapsed time since the last request from the client. If the time elapsed is within the current time window, it increments the request count. If the request count exceeds the maximum allowed requests, the system rejects the request with a false response. Time Window Reset:
If the elapsed time exceeds the defined time window, the system resets the request count and updates the last request time.
The getClientKey method generates a unique key for each client based on their identifier.
The allowRequest method is the entry point for handling incoming requests. It returns true if the request is allowed, and false if the client has exceeded the maximum allowed requests within the specified time window.
For high-performance search functionality, text indexing has been implemented using ts_vector function of Postgre SQL to ensure fast and efficient notes search as per keyword/query provided.
POST /api/auth/signup: Create a new user account.
POST /api/auth/login: Log in to an existing user account and receive an access token.
GET /api/notes: Get a list of all notes for the authenticated user.
GET /api/notes/{id}: Get a note by ID for the authenticated user.
POST /api/notes: Create a new note for the authenticated user.
PUT /api/notes/{id}: Update an existing note by ID for the authenticated user.
DELETE /api/notes/{id}: Delete a note by ID for the authenticated user.
POST /api/notes/{id}/share: Share a note with another user for the authenticated user.
GET /api/search?q={query}: Search for notes based on keywords for the authenticated user.
- Java 17 or higher
- Maven
- Postgre SQL
- Postman
spring.jpa.hibernate.ddl-auto=update spring.datasource.url=jdbc:postgresql://localhost:5432/postgres spring.datasource.username=postgres spring.datasource.password=root spring.datasource.driver-class-name =org.postgresql.Driver spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect spring.jpa.show-sql=true
logging.level.org.springframework.security=DEBUG
jwt.secret= afafasfafafasfasfasfafacasdasfasxASFACASDFACASDFASFASFDAFASFASDAADSCSDFADCVSGCFVADXCcadwavfsfarvf
- Steps to Run:
- Clone the repository:
git clone <Your GitHub Repository URL>
- Navigate to the project directory:
cd <project-directory>
- Run the application:
./mvnw spring-boot:run
- Access the API at http://localhost:8080
- Clone the repository:
POST /api/auth/signup
Parameter | Type | Description |
---|---|---|
name |
string |
Required. username minimum character 4 |
email |
string |
Required. user email address |
password |
string |
Required. password character between 3 and 10 |
about |
string |
Required. description about user |
{ "name":"sample_name", "email":"sample@gmail.com", "password":"abcdefg", "about":"Software Test Engineer" }
{ "id": 11, "name": "sample_name", "email": "sample@gmail.com", "password": "$2a$10$zkzMRMhehddqlqA6UXkeouY/BseaIuYjTr1MgwXH9cDwDW8L0SUsS", "about": "Software Test Engineer", "roles": [ { "id": 502, "name": "NORMAL_USER" } ] }
POST /api/auth/login
Parameter | Type | Description |
---|---|---|
userId |
String |
Required. Id of user |
password |
String |
Required. password of user |
{ "userId" : "3", "password" : "abcde" }
{ "token": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIzIiwiaWF0IjoxNzA0NjI2ODIyLCJleHAiOjE3MDQ2NDQ4MjJ9.VcHxvu-NV4oyEyrJkxrqf4yP-Zt8Mss6_6PWqmxPsCA", "userDto": { "id": 3, "name": "SampleUser", "email": "sample@gmail.com", "password": "$2a$10$fXkzPZLA9DVPnYhyJkvom.ZzLKklWn4pAU.HMaW21/GIYrktRCkTq", "about": "Sample about content", "roles": [ { "id": 502, "name": "NORMAL_USER" } ] } }
To create admin user Request Param "admin" can be passed as mentioned below. Admin user can perform User CRUD operations.
POST /api/auth/login?role=admin
GET /api/notes
Parameter | Type | Description |
---|---|---|
Authorization |
string |
Required. Request Header |
{ "content": [ { "notesId": 1, "userId": 3, "title": "Notes1-Java", "content": "Java is a programming language used to write code which can be understood by machine.", "addedDate": "2024-01-07T11:39:11.614+00:00" }, { "notesId": 2, "userId": 3, "title": "Notes2-Python", "content": "Python is a programming language used to write code which can be understood by machine.", "addedDate": "2024-01-07T11:39:56.254+00:00" } ] }
GET /api/notes/{id}
Parameter | Type | Description |
---|---|---|
Authorization |
string |
Required. Request Header |
notesId |
Integer |
Required. Request Param |
{ "notesId": 1, "userId": 3, "title": "Notes1-Java", "content": "java is a programming language used to write code which can be understood by machine.", "addedDate": 1704293862752 }
POST /api/notes
Parameter | Type | Description |
---|---|---|
userId |
Integer |
Required. userId to create note for that user |
title |
string |
Required. title of note minimum 4 characters |
content |
string |
Required. content of note minimum 10 characters |
Authorization |
string |
Required. Request Header |
{ "userId":2, "title":"Notes6-C#", "content":"C# is a programming language used to write code which can be understood by machine." }
{ "notesId": 7, "userId": 2, "title": "Notes6-C#", "content": "C# is a programming language used to write code which can be understood by machine.", "addedDate": 1704445889013 }
PUT /api/notes
Parameter | Type | Description |
---|---|---|
notesId |
Integer |
Required. notesId to update that note |
title |
string |
Required. to update title of note |
content |
string |
Required. to update content of note |
Authorization |
string |
Required. Request Header |
{ "notesId":7, "title":"Notes6-C#-updated", "content":"C# is a programming language used to write code which can be understood by machine." }
{ "notesId": 7, "userId": 2, "title": "Notes6-C#-updated", "content": "C# is a programming language used to write code which can be understood by machine.", "addedDate": 1704445889013 }
DELETE /api/notes/{id}
Parameter | Type | Description |
---|---|---|
Authorization |
string |
Required. Request Header |
notesId |
Integer |
Required. Request Param |
{ "message": "Notes deleted Successfully", "statusCode": true }
POST /api/notes/{id}/share
Parameter | Type | Description |
---|---|---|
Authorization |
string |
Required. Request Header |
userId |
Integer |
Required. Request Param userId of user to share notes |
userId |
string |
Required. userId of sharing user |
title |
string |
Required. title of note |
content |
string |
Required. content of note |
{ "userId":11, "title":"Notes5-C-share", "content":"C is a programming language used to write code which can be understood by machine." }
{ "message": "Notes shared successfully with the user : 1", "status": "0", "notesDto": { "notesId": 8, "userId": 1, "title": "Notes5-C-share", "content": "C is a programming language used to write code which can be understood by machine.", "addedDate": 1704447655040 } }
GET /api/search?q=:query
Parameter | Type | Description |
---|---|---|
Authorization |
string |
Required. Request Header |
q |
String |
Required. Params to pass search keyword |
[ { "notesId": 1, "userId": 1, "title": "Notes1-Java", "content": "java is a programming language used to write code which can be understood by machine.", "addedDate": 1704293862752 } ]