Welcome a simple Chat API, built by @georgerappel!
I've included some docs for reference and simplicty (and maybe for myself in the future).
- Most of the relevant app logic sits in app/UserController and app/ChatController.
- The app/routes.php file simply calls the controllers
- Very few abstractions/models were used to keep a simple architecture using mostly Slim 4, without ORMs or DB helpers aside from native PHP SQLite3 library.
- Simple back-end for a chat application
- It uses PHP 8.1 + Slim 4 + SQLite
- Docker support was used to reduce overhead when building it locally (Thanks to this post for providing a quick boilerplate)
To run the project using docker:
- Build and run:
docker-compose up -d --build
- Go to http://localhost:8080/
- To see real-time logs:
docker-compose logs -f
- Create username, using POST /users
- Optionally, search for a username
- Open a chat with another user, using GET /chat/{other_user}
Comment out lines 11-18 on the AuthMiddleware.php, and uncomment line 20 with your user ID from the POST /users route.
- For authorization, a simple logic expects the username in the Authorization header of a request, instead of bearer tokens
Users are 'public', and no authorization is required to create, search or list users.
- POST /users - Create user, expects a JSON body with
{"username": "myname"}
- IF the username is available, returns HTTP 200 OK with
{"id": 1234}
- IF the username is not available, returns HTTP 409 CONFLICT with
{"error": "Username taken"}
- IF the username is available, returns HTTP 200 OK with
- GET /users?query={name} - Read all users, optionally provide a query for searching usernames, returns HTTP 200 OK with
{"users": [{"username": "myname", "id": 123, "created_at": "2022-12-22 12:00:00"}, ...]}
- GET /users/{username} - Read user, returns
{"username": "myname", "id": 123, "created_at": "2022-12-22 12:00:00"}
Authorization is required for all routes.
- GET /chat/{other_user} - Reads messages from a chat, returns last 20 messages.
- IF the chat was never used, returns an empty array
- ELSE returns up to 20 messages:
{"messages": [{"id": 1, "content": "Hi, this is my message", "sender": 1, "recipient": 2, "created_at": "2022-12-22 12:00:00"}, {"id": 2, "content": "Hi myname, heres my message as well", "sender": 2, "recipient": 1, "created_at": "2022-12-22 13:00:00"}], "first_message": 1, "last_message": 2}
- To load previous/older messages, use the
?before={first_meswsage}
query param with the first message received on a previous request to load older messages - To Poll for new messages, use the
?after={last_message}
query param with the last_message from the first request made, this will load newer messages.
- POST /chat/{other_user} - Send a message to "other_user", expects a JSON body with
{"content": "Plain text message"}
- Returns the message just created:
{"id":8,"sender":1,"recipient":4,"created_at":"2022-12-22 21:19:25","content":"My first message"}
- Returns the message just created:
- Add a route
GET /users/{id}/online
to check wether the user is currently online, based on their last poll for messages, storing this in a simple 30sec cache or in a column on the user table. - Add indexes to the sender/recipient columns on the message table to speed up queries
- Add an error handler for exceptions, currently raising exceptions such as HttpNotFoundException returns HTTP 200 OK with the trace on the body, instead of the 404 NOT FOUND.