A simple REST API for a flashcard application where users can create accounts, log in with a session cookie, organize flashcards into decks, and manage cards inside those decks.
This API is meant for a frontend client such as:
- a web app
- a mobile app
- a desktop study app
- Postman or cURL for testing
With this API, a user can:
- register an account
- log in and receive an authentication cookie
- create decks to organize study topics
- add flashcards to a deck
- fetch their decks and cards
- delete decks or cards
- log out and destroy their session
http://localhost:8080
This API uses cookie-based authentication.
When a user logs in successfully, the backend returns an auth cookie.
That cookie must be included in future requests to protected endpoints.
These do not require login:
POST /user/registerPOST /user/login
These require the auth cookie:
GET /user/logoutPOST /deckGET /deckDELETE /deck/delete/{id}POST /card/{id}GET /card/{id}/deckDELETE /card/delete/{id}
- User registers an account
- User logs in
- Server returns an
authcookie - Client stores and sends the cookie on future requests
- Protected endpoints use that cookie to identify the user
- User logs out to delete the session
For browser-based frontend apps, use
credentials: "include"so cookies are sent with requests.
Represents an account in the system.
A user can:
- create an account
- log in
- own multiple decks
- create cards under their account
A deck is a collection of flashcards grouped by topic.
Examples:
- Java Interview Questions
- Biology Chapter 3
- Spring Boot Notes
- Chinese Vocabulary
Each deck belongs to one authenticated user.
A card is a single flashcard inside a deck.
Each card contains:
- a question
- an answer
Example:
- Question:
What is dependency injection? - Answer:
A pattern where dependencies are provided from outside the class.
POST /user/register
Creates a new user account.
Use this when a new user signs up for the app.
{
"name": "dina",
"password": "mypassword123"
}const response = await fetch("http://localhost:8080/user/register", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
name: "dina",
password: "mypassword123"
})
});
console.log(response.status); // 201201 Created
No response body.
POST /user/login
Authenticates a user and creates a session.
Use this when a user wants to access protected features such as creating decks or cards.
{
"name": "dina",
"password": "mypassword123"
}const response = await fetch("http://localhost:8080/user/login", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
credentials: "include",
body: JSON.stringify({
name: "dina",
password: "mypassword123"
})
});
const text = await response.text();
console.log(response.status); // 200
console.log(text); // "Login successful"200 OK
Set-Cookie: auth=<session-token>; HttpOnly; Path=/Login successful
- the backend checks the username and password
- if valid, it creates a session
- it sends back an
authcookie - that cookie is used for future protected requests
GET /user/logout
Deletes the current session.
Use this when the user wants to sign out.
const response = await fetch("http://localhost:8080/user/logout", {
method: "GET",
credentials: "include"
});
console.log(response.status); // 200200 OK
No response body.
POST /deck
Creates a new deck for the authenticated user.
Use this when a user wants to organize flashcards under a topic or subject.
{
"name": "Java Basics",
"description": "Cards for Java interview prep"
}const response = await fetch("http://localhost:8080/deck", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
credentials: "include",
body: JSON.stringify({
name: "Java Basics",
description: "Cards for Java interview prep"
})
});
const deckId = await response.json();
console.log(response.status); // 200
console.log(deckId);200 OK
"550e8400-e29b-41d4-a716-446655440000"GET /deck
Returns all decks that belong to the authenticated user.
Use this to show a user's deck list on the frontend.
const response = await fetch("http://localhost:8080/deck", {
method: "GET",
credentials: "include"
});
const decks = await response.json();
console.log(response.status); // 200
console.log(decks);200 OK
[
{
"deckId": "550e8400-e29b-41d4-a716-446655440000",
"name": "Java Basics",
"description": "Cards for Java interview prep",
"userID": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
},
{
"deckId": "123e4567-e89b-12d3-a456-426614174000",
"name": "Spring Boot",
"description": "Spring notes",
"userID": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
}
]DELETE /deck/delete/{id}
Deletes a deck by its ID.
Use this when the user wants to remove an entire deck.
id= deck UUID
const deckId = "550e8400-e29b-41d4-a716-446655440000";
const response = await fetch(`http://localhost:8080/deck/delete/${deckId}`, {
method: "DELETE",
credentials: "include"
});
console.log(response.status); // 200200 OK
No response body.
POST /card/{id}
Creates a new card inside a deck.
Use this when the user wants to add a flashcard to a specific deck.
id= deck UUID
{
"question": "What is dependency injection?",
"answer": "A design pattern where dependencies are provided from outside the class."
}const deckId = "550e8400-e29b-41d4-a716-446655440000";
const response = await fetch(`http://localhost:8080/card/${deckId}`, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
credentials: "include",
body: JSON.stringify({
question: "What is dependency injection?",
answer: "A design pattern where dependencies are provided from outside the class."
})
});
const card = await response.json();
console.log(response.status); // 200
console.log(card);200 OK
{
"question": "What is dependency injection?",
"answer": "A design pattern where dependencies are provided from outside the class."
}GET /card/{id}/deck
Returns all cards that belong to a specific deck.
Use this when the frontend opens a deck and needs to display all its flashcards.
id= deck UUID
const deckId = "550e8400-e29b-41d4-a716-446655440000";
const response = await fetch(`http://localhost:8080/card/${deckId}/deck`, {
method: "GET",
credentials: "include"
});
const cards = await response.json();
console.log(response.status); // 200
console.log(cards);200 OK
[
{
"cardId": "11111111-1111-1111-1111-111111111111",
"question": "What is IOC?",
"answer": "Inversion of Control",
"userId": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
"deckId": "550e8400-e29b-41d4-a716-446655440000"
},
{
"cardId": "22222222-2222-2222-2222-222222222222",
"question": "What is dependency injection?",
"answer": "A pattern where dependencies are provided from outside the class.",
"userId": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
"deckId": "550e8400-e29b-41d4-a716-446655440000"
},
{
"cardId": "33333333-3333-3333-3333-333333333333",
"question": "What is Spring Boot?",
"answer": "A framework that simplifies building Spring applications.",
"userId": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
"deckId": "550e8400-e29b-41d4-a716-446655440000"
}
]DELETE /card/delete/{id}
Deletes a card by its ID.
Use this when the user wants to remove a single flashcard.
id= card UUID
const cardId = "11111111-1111-1111-1111-111111111111";
const response = await fetch(`http://localhost:8080/card/${cardId}`, {
method: "DELETE",
credentials: "include"
});
console.log(response.status); // 200200 OK
No response body.
A frontend app would usually use the API in this order:
Call:
POST /user/register
Request example:
await fetch("http://localhost:8080/user/register", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
name: "dina",
password: "mypassword123"
})
});Response example:
201 Created
Call:
POST /user/login
Request example:
await fetch("http://localhost:8080/user/login", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
credentials: "include",
body: JSON.stringify({
name: "dina",
password: "mypassword123"
})
});Response example:
Login successful
The browser or client stores the returned auth cookie.
Call:
POST /deck
Request example:
await fetch("http://localhost:8080/deck", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
credentials: "include",
body: JSON.stringify({
name: "Spring Boot Interview",
description: "Study deck for Spring Boot concepts"
})
});Response example:
"550e8400-e29b-41d4-a716-446655440000"Call:
POST /card/{deckId}
Request example:
await fetch("http://localhost:8080/card/550e8400-e29b-41d4-a716-446655440000", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
credentials: "include",
body: JSON.stringify({
question: "What is JVM?",
answer: "Java Virtual Machine"
})
});Response example:
{
"question": "What is JVM?",
"answer": "Java Virtual Machine"
}Call:
GET /deckto show all decksGET /card/{deckId}/deckto show cards in a selected deck
Deck request example:
await fetch("http://localhost:8080/deck", {
method: "GET",
credentials: "include"
});Deck response example:
[
{
"deckId": "550e8400-e29b-41d4-a716-446655440000",
"name": "Spring Boot Interview",
"description": "Study deck for Spring Boot concepts",
"userID": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
}
]Card request example:
await fetch("http://localhost:8080/card/550e8400-e29b-41d4-a716-446655440000/deck", {
method: "GET",
credentials: "include"
});Card response example:
[
{
"cardId": "11111111-1111-1111-1111-111111111111",
"question": "What is JVM?",
"answer": "Java Virtual Machine",
"userId": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
"deckId": "550e8400-e29b-41d4-a716-446655440000"
}
]Call:
DELETE /deck/delete/{id}DELETE /card/delete/{id}
Request example:
await fetch("http://localhost:8080/card/11111111-1111-1111-1111-111111111111", {
method: "DELETE",
credentials: "include"
});Response example:
200 OK- no response body
Call:
GET /user/logout
Request example:
await fetch("http://localhost:8080/user/logout", {
method: "GET",
credentials: "include"
});Response example:
200 OK- no response body
A student using a study app might do the following:
- Register an account
- Log in
- Create a deck called
Spring Boot Interview - Add cards such as:
What is IOC?What is dependency injection?Difference between @Component and @Service?
- Open the deck later to review all cards
- Delete cards they no longer need
- Log out
- This API is session-based, not token-based
- Authentication depends on the
authcookie - All deck and card operations require login
- Decks help group related cards together
- Cards store the actual study question and answer pairs
These are common examples for frontend documentation.
{
"error": "Invalid request body"
}{
"error": "Unauthorized"
}{
"error": "Resource not found"
}{
"error": "Something went wrong"
}| Method | Endpoint | Example Request | Example Response | Auth Required |
|---|---|---|---|---|
| POST | /user/register |
fetch("/user/register", { method: "POST", body: JSON.stringify({ name, password }) }) |
No body | No |
| POST | /user/login |
fetch("/user/login", { method: "POST", credentials: "include", body: JSON.stringify({ name, password }) }) |
"Login successful" |
No |
| GET | /user/logout |
fetch("/user/logout", { method: "GET", credentials: "include" }) |
No body | Yes |
| POST | /deck |
fetch("/deck", { method: "POST", credentials: "include", body: JSON.stringify({ name, description }) }) |
"550e8400-e29b-41d4-a716-446655440000" |
Yes |
| GET | /deck |
fetch("/deck", { method: "GET", credentials: "include" }) |
Array of deck objects | Yes |
| DELETE | /deck/delete/{id} |
fetch("/deck/delete/{id}", { method: "DELETE", credentials: "include" }) |
No body | Yes |
| POST | /card/{id} |
fetch("/card/{id}", { method: "POST", credentials: "include", body: JSON.stringify({ question, answer }) }) |
Card summary object | Yes |
| GET | /card/{id}/deck |
fetch("/card/{id}/deck", { method: "GET", credentials: "include" }) |
Array of card objects | Yes |
| DELETE | /card/delete/{id} |
fetch("/card/{id}", { method: "DELETE", credentials: "include" }) |
No body | Yes |