A basic RESTful API with token-based authentication in PHP for "Task List" application.
Note: It's a test project. Don't use in for production application.
- PHP
- MySQL
I used the Apache server. However, it should work on any server which supports .htacccess
files because it contains routing information.
Note: The php_flag display_errors
on should be removed from the .htaccess
file before installing to server.
Database name: tasks-db.
Tables:
- Users (tbl_users)
- Sessions (tbl_sessions)
- Tasks (tbl_tasks)
Note: If you want to use different names of database and tables, remember to update source code.
Basic use case of using API for creating account, adding tasks to logged in user and log out.
Additional features:
- /v1/users/
POST
Create a new user account (see requirements).
- /v1/sessions/
POST
Log in (Create a new user session) (see requirements).
- /v1/sessions/SESSION_ID
PATCH
Refresh access and refresh tokens, based onSESSION_ID
. (see requirements).DELETE
Log out (Delete existing session) (see requirements).
- /v1/tasks/
GET
Get all tasks (see requirements).POST
Create a new task (see requirements).
- /v1/tasks/page/PAGE
GET
Get tasks by page number (see requirements).
- /v1/tasks/complete
GET
Get list of completed tasks (see requirements).
- /v1/tasks/incomplete
GET
Get list of incompleted tasks (see requirements).
- /v1/tasks/TASK_ID
GET
Get tasks by ID (see requirements).PATCH
Update task by ID (see requirements).DELETE
Delete task by ID (see requirements).
Description of basic requirements for each request.
Label | Value |
---|---|
Method | POST |
URL | /tasks-rest-api/v1/users |
Header | Content-Type : application/json |
Body | { "fullname": "FULL_NAME" , "username": "USER_NAME" , "password": "PASSWORD" } |
The request contains user data: FULL_NAME
, USER_NAME
and PASSWORD
.
Response:
{
"statusCode": 201,
"success": true,
"messages": ["User created"],
"data": {
"user_id": "ID",
"fullname": "FULL_NAME",
"username": "USER_NAME"
}
}
Label | Value |
---|---|
Method | POST |
URL | /tasks-rest-api/v1/sessions |
Header | Content-Type : application/json |
Body | { "username": "USER_NAME" , "password": "PASSWORD" } |
The request contains user data: USER_NAME
and PASSWORD
.
Response:
{
"statusCode": 200,
"success": true,
"messages": [],
"data": {
"user_id": "ID",
"fullname": "FULL_NAME",
"username": "USER_NAME"
}
}
Label | Value |
---|---|
Method | PATCH |
URL | /tasks-rest-api/v1/sessions/SESSION_ID |
Header | Content-Type : application/json Authorization : ACCESS_TOKEN |
Body | { "refresh_token": "REFRESH_TOKEN" } |
The request contains user data: SESSION_ID
, ACCESS_TOKEN
and REFRESH_TOKEN
.
Response:
{
"statusCode": 200,
"success": true,
"messages": ["Token refreshed"],
"data": {
"session_id": SESSION_ID,
"access_token": "ACCESS_TOKEN",
"access_token_expires_in": ACCESS_TOKEN_EXPIRY,
"refresh_token": "REFRESH_TOKEN",
"refresh_token_expires_in": REFRESH_TOKEN_EXPIRY
}
}
Label | Value |
---|---|
Method | DELETE |
URL | /tasks-rest-api/v1/sessions/SESSION_ID |
Header | Authorization : ACCESS_TOKEN |
The request contains user data: SESSION_ID
and ACCESS_TOKEN
.
Response:
{
"statusCode": 200,
"success": true,
"messages": ["Logged out"],
"data": {
"session_id": SESSION_ID
}
}
Label | Value |
---|---|
Method | GET |
URL | /tasks-rest-api/v1/tasks |
Header | Authorization : ACCESS_TOKEN |
The request contains user data: ACCESS_TOKEN
.
Response:
{
"statusCode": 200,
"success": true,
"messages": [],
"data": {
"row_returned": TASKS_COUNT,
"tasks": [
{
"id": TASK_ID,
"title": "TASK_TITLE",
"description": "TASK_DESCRIPTION",
"deadline": "TASK_DEADLINE",
"completed": "TASK_COMPLETED" // 'Y' or 'N'
},
{
"id": TASK_ID,
"title": "TASK_TITLE",
"description": "TASK_DESCRIPTION",
"deadline": "TASK_DEADLINE",
"completed": "TASK_COMPLETED" // 'Y' or 'N'
}
]
}
}
Label | Value |
---|---|
Method | POST |
URL | /tasks-rest-api/v1/tasks |
Header | Content-Type : application/json Authorization : ACCESS_TOKEN |
Body | { "title": "TASK_TITLE" ,"description": "TASK_DESCRIPTION" , //optional"deadline": "TASK_DEADLINE" , //optional, date format: 01/01/2019 01:00"completed": "TASK_COMPLETED" // N - incompleted, Y - completed} |
The request contains user data: ACCESS_TOKEN
, TASK_TITLE
, TASK_DESCRIPTION
, TASK_DEADLINE
and TASK_COMPLETED
.
Response:
{
"statusCode": 201,
"success": true,
"messages": ["Task created"],
"data": {
"rows_returned": 1,
"tasks": [
{
"id": TASK_ID,
"title": "TASK_TITLE",
"description": "TASK_DESCRIPTION",
"deadline": "TASK_DEADLINE",
"completed": "TASK_COMPLETED" // 'Y' or 'N'
}
]
}
}
Label | Value |
---|---|
Method | GET |
URL | /tasks-rest-api/v1/tasks/page/PAGE_NUMBER |
Header | Authorization : ACCESS_TOKEN |
The request contains user data: PAGE_NUMBER
and ACCESS_TOKEN
.
Response:
{
"statusCode": 200,
"success": true,
"messages": [],
"data": {
"row_returned": TASKS_COUNT_ON_PAGE,
"total_rows": TASKS_COUNT,
"total_pages": TOTAL_PAGES_COUNT,
"has_next_page": true|false,
"has_previous_page": true|false,
"tasks": [
{
"id": TASK_ID,
"title": "TASK_TITLE",
"description": "TASK_DESCRIPTION",
"deadline": "TASK_DEADLINE",
"completed": "TASK_COMPLETED" // 'Y' or 'N'
},
{
"id": TASK_ID,
"title": "TASK_TITLE",
"description": "TASK_DESCRIPTION",
"deadline": "TASK_DEADLINE",
"completed": "TASK_COMPLETED" // 'Y' or 'N'
}
]
}
}
Label | Value |
---|---|
Method | GET |
URL | /tasks-rest-api/v1/tasks/complete |
Header | Authorization : ACCESS_TOKEN |
The request contains user data: ACCESS_TOKEN
.
Response:
{
"statusCode": 200,
"success": true,
"messages": [],
"data": {
"row_returned": TASKS_COUNT,
"tasks": [
{
"id": TASK_ID,
"title": "TASK_TITLE",
"description": "TASK_DESCRIPTION",
"deadline": "TASK_DEADLINE",
"completed": "TASK_COMPLETED" // 'Y' or 'N'
},
{
"id": TASK_ID,
"title": "TASK_TITLE",
"description": "TASK_DESCRIPTION",
"deadline": "TASK_DEADLINE",
"completed": "TASK_COMPLETED" // 'Y' or 'N'
}
]
}
}
Label | Value |
---|---|
Method | GET |
URL | /tasks-rest-api/v1/tasks/incomplete |
Header | Authorization : ACCESS_TOKEN |
The request contains user data: ACCESS_TOKEN
.
Response:
{
"statusCode": 200,
"success": true,
"messages": [],
"data": {
"row_returned": TASKS_COUNT,
"tasks": [
{
"id": TASK_ID,
"title": "TASK_TITLE",
"description": "TASK_DESCRIPTION",
"deadline": "TASK_DEADLINE",
"completed": "TASK_COMPLETED" // 'Y' or 'N'
},
{
"id": TASK_ID,
"title": "TASK_TITLE",
"description": "TASK_DESCRIPTION",
"deadline": "TASK_DEADLINE",
"completed": "TASK_COMPLETED" // 'Y' or 'N'
}
]
}
}
Label | Value |
---|---|
Method | GET |
URL | /tasks-rest-api/v1/tasks/TASK_ID |
Header | Authorization : ACCESS_TOKEN |
The request contains user data: TASK_ID
and ACCESS_TOKEN
.
Response:
"statusCode": 200,
"success": true,
"messages": [],
"data": {
"rows_returned": 1,
"tasks": {
"id": TASK_ID,
"title": "TASK_TITLE",
"description": "TASK_DESCRIPTION",
"deadline": "TASK_DEADLINE",
"completed": "TASK_COMPLETED" // 'Y' or 'N'
}
}
Label | Value |
---|---|
Method | PATCH |
URL | /tasks-rest-api/v1/tasks/TASK_ID |
Header | Authorization : ACCESS_TOKEN |
Body | { "title": "TASK_TITLE" ,"description": "TASK_DESCRIPTION" , //optional"deadline": "TASK_DEADLINE" , //optional, date format: 01/01/2019 01:00"completed": "TASK_COMPLETED" // N - incompleted, Y - completed} |
The request contains user data: TASK_ID
, ACCESS_TOKEN
, TASK_TITLE
, TASK_DESCRIPTION
, TASK_DEADLINE
and TASK_COMPLETED
..
Response:
{
"statusCode": 200,
"success": true,
"messages": ["Task updated"],
"data": {
"rows_returned": 1,
"tasks": {
"id": TASK_ID,
"title": "TASK_TITLE",
"description": "TASK_DESCRIPTION",
"deadline": "TASK_DEADLINE",
"completed": "TASK_COMPLETED" // 'Y' or 'N'
}
}
}
Label | Value |
---|---|
Method | DELETE |
URL | /tasks-rest-api/v1/tasks/TASK_ID |
Header | Authorization : ACCESS_TOKEN |
The request contains user data: TASK_ID
and ACCESS_TOKEN
.
Response:
{
"statusCode": 200,
"success": true,
"messages": ["Task deleted"],
"data": null
}