Creating a minimum viable bulletin board REST API for educational purposes.
Getting lists of all tags, posts and users
Search in lists
User registration
A registered user can:
Add new posts
Comment on existing posts
Delete and edit your posts and comments
PHP 8.1+
Laravel 10
Composer
MySQL
POST
/api/v1/auth/register
RegisterName | Type | Data type | Description |
---|---|---|---|
name | required | string | Name |
nickname | required | string | Human-readable identifier |
required | string | Email address | |
password | required | string | Password |
password_confirmed | required | string | Password confirmation |
201
CREATED
{ "access_token", "token_type": "Bearer" }
POST
/api/v1/auth/login
LoginName | Type | Data type | Description |
---|---|---|---|
required | string | Email address | |
password | required | string | Password |
200
OK
{ "access_token", "token_type":"Bearer" }
POST
/api/v1/auth/logout
LogoutKey | Value |
---|---|
Authorization | Bearer {token} |
204
NO CONTENT
GET
/api/v1/profile
Get authenticated user profileKey | Value |
---|---|
Authorization | Bearer {token} |
200
OK
{ "data": { "user_id", "name", "nickname", "email", "created_at", "updated_at", "posts_count", "comments_count" } }
GET
/api/v1/profile/posts
Get the profile and posts of an authenticated userKey | Value |
---|---|
Authorization | Bearer {token} |
Name | Type | Data type | Description |
---|---|---|---|
per_page | optional | int | Number of posts per page |
page | optional | int | Page number |
200
OK
{ "data": [ { "post_id", "title", "price", "description", "created_at", "updated_at", "user_id", "user_nickname", "tags": [ { "tag_id", "name", "slug", }, ... ], "comments_count" } ], "links": {...}, "meta": {...}, "user": { "user_id", "name", "nickname", "email", "created_at", "updated_at" } }
GET
/api/v1/profile/comments
Get the profile and comments of an authenticated userKey | Value |
---|---|
Authorization | Bearer {token} |
Name | Type | Data type | Description |
---|---|---|---|
per_page | optional | int | Number of comments per page |
page | optional | int | Page number |
200
OK
{ "data": [ { "comment_id", "body", "created_at":, "updated_at", "post_id", "user_id", "user_nickname" }, ... ], "links": {...}, "meta": {...}, "user": { "user_id", "name", "nickname", "email", "created_at", "updated_at" } }
GET
/api/v1/users
Get all usersName | Type | Data type | Description |
---|---|---|---|
q | optional | string | Search query |
per_page | optional | int | Number of users per page |
page | optional | int | Page number |
200
OK
{ "data": [ { "user_id", "name", "nickname", "email", "created_at", "updated_at", "posts_count", "comments_count" }, ... ], "links": {...}, "meta": {...} }
GET
/api/v1/users/{nickname}
Get user200
OK
{ "data": { "user_id", "name", "nickname", "email", "created_at", "updated_at", "posts_count", "comments_count" } }
GET
/api/v1/users/{nickname}/posts
Get the user and his postsName | Type | Data type | Description |
---|---|---|---|
per_page | optional | int | Number of posts per page |
page | optional | int | Page number |
200
OK
{ "data": [ { "post_id", "title", "price", "description", "created_at", "updated_at", "user_id", "user_nickname", "tags": [ { "tag_id", "name", "slug" }, ... ], "comments_count" }, ... ], "links": {...}, "meta": {...}, "user": { "user_id", "name", "nickname", "email", "created_at", "updated_at" } }
GET
/api/v1/users/{nickname}/comments
Get the user and his commentsName | Type | Data type | Description |
---|---|---|---|
per_page | optional | int | Number of comments per page |
page | optional | int | Page number |
200
OK
{ "data": [ { "comment_id", "body", "created_at":, "updated_at", "post_id", "user_id", "user_nickname" }, ... ], "links": {...}, "meta": {...}, "user": { "user_id", "name", "nickname", "email", "created_at", "updated_at" } }
GET
/api/v1/tags
Get all tagsName | Type | Data type | Description |
---|---|---|---|
q | optional | string | Search query |
200
OK
{ "data": [ { "tag_id", "name", "slug", "post_count" }, ... ] }
GET
/api/v1/tags/{slug}
Get a tag and its postsName | Type | Data type | Description |
---|---|---|---|
per_page | optional | int | Number of posts per page |
page | optional | int | Page number |
200
OK
{ "data": [ { "post_id", "title", "price", "description", "created_at", "updated_at", "user_id", "user_nickname" }, ], "links": {...}, "meta": {...}, "tag": { "tag_id", "name", "slug" } }
GET
/api/v1/posts
Get all postsName | Type | Data type | Description |
---|---|---|---|
q | optional | string | Search query |
per_page | optional | int | Number of posts per page |
page | optional | int | Page number |
200
OK
{ "data": [ { "post_id, "title", "price", "description", "created_at", "updated_at", "user_id", "user_nickname", "tags": [ { "tag_id", "name", "slug" }, ... ], "comments_count" }, ... ], "links": {...}, "meta": {...} }
GET
/api/v1/posts/{id}
Get a post and its commentsName | Type | Data type | Description |
---|---|---|---|
per_page | optional | int | Number of comments per page |
page | optional | int | Page number |
200
OK
{ "data": [ { "comment_id", "body", "created_at", "updated_at", "post_id", "user_id", "user_nickname" }, ... ], "links": {...}, "meta": {...}, "post": { "post_id", "title", "price", "description", "created_at", "updated_at", "user_id", "user_nickname", "tags": [ { "tag_id", "name", "slug" }, ... ] } }
POST
/api/v1/posts
Add new postKey | Value |
---|---|
Authorization | Bearer {token} |
Name | Type | Data type | Description |
---|---|---|---|
title | optional | string | Title |
price | optional | float | Price |
description | optional | string | Description |
tags[id] | optional | array[int] | Array of tag IDs |
201
CREATED
{ "data": { "post_id", "title", "price", "description", "created_at", "updated_at", "user_id", "user_nickname", "tags": [ { "tag_id", "name", "slug" }, ... ] }, }
PUT
/api/v1/posts/{id}
Edit postKey | Value |
---|---|
Authorization | Bearer {token} |
Name | Type | Data type | Description |
---|---|---|---|
title | optional | string | Title |
price | optional | float | Price |
description | optional | string | Description |
tags[id] | optional | array[int] | Array of tag IDs |
200
OK
{ "data": { "post_id", "title", "price", "description", "created_at", "updated_at", "user_id", "user_nickname", "tags": [ { "tag_id", "name", "slug" }, ... ] }, }
DELETE
/api/v1/posts/{id}
Delete a postKey | Value |
---|---|
Authorization | Bearer {token} |
204
NO CONTENT
POST
/api/v1/posts/{id}/comments
Add a new comment to a postKey | Value |
---|---|
Authorization | Bearer {token} |
Name | Type | Data type | Description |
---|---|---|---|
body | required | string | Comment text |
201
CREATED
{ "data": { "comment_id", "body", "created_at", "updated_at", "post_id", "user_id", "user_nickname", }, }
PUT
/api/v1/comments/{id}
Edit commentKey | Value |
---|---|
Authorization | Bearer {token} |
Name | Type | Data type | Description |
---|---|---|---|
body | required | string | Comment text |
200
OK
{ "data": { "comment_id", "body", "created_at", "updated_at", "post_id", "user_id", "user_nickname", } }
DELETE
/api/v1/comments/{id}
Delete a commentKey | Value |
---|---|
Authorization | Bearer {token} |
204
NO CONTENT
Clone this repository and go to your project folder:
git clone https://github.com/AllaAverina/bulletin-board-APIcd bulletin-board-API
Install dependencies:
composer install
Start MySQL, change the parameters for connecting to the database in the .env.example file and run:
copy .env.example .env
Run the command to run the migrations:
php artisan migrate
Or if you want to populate the database with dummy data:
php artisan migrate --seed
Start the web server:
php artisan serve
Open in your browser, for example, http://localhost:8000/api/v1/posts
Create a new database for testing, change the parameters to connect to it in the .env.testing file and run:
php artisan test
Clone this repository and go to your project folder:
git clone https://github.com/AllaAverina/bulletin-board-APIcd bulletin-board-API
Install dependencies:
docker run --rm -u "$(id -u):$(id -g)" -v "$(pwd):/var/www/html" -w /var/www/html laravelsail/php82-composer:latest composer install --ignore-platform-reqs
Create a .env file:
cp.env.docker.examlpe.env
Create a shell alias and run sail:
alias sail='[ -f sail ] && sh sail || sh vendor/bin/sail'sail up -d
Run the command to run the migrations:
sail artisan migrate
Or if you want to populate the database with dummy data:
sail artisan migrate --seed
Open in a browser, for example, http://localhost/api/v1/posts
To stop containers use:
sail stop
Set up the .env.testing file:
cp .env.docker.testing .env.testing
Run the tests:
sail artisan test