This application implements REST API using Hibernate/Spring/SpringMVC/Spring DATA-JPA technologies. Security is provided by Spring Security and based on user roles. The application provides the following requirements:
- 2 types of users: admin and regular users
- Admin can input a restaurant and it's lunch menu of the day (2-5 items usually, dish name and price)
- Menu changes each day (admins do the updates)
- Users can vote on which restaurant they want to have lunch at
- Only one vote counted per user
- If user votes again the same day:
- If it is before 11:00 it's asume that he changed his mind.
- If it is after 11:00 then it is too late, vote can't be changed
#####USER-available operations:
- get list of restaurants with menu for current date (or any specified date)
- vote for the restaurant (once a day)
- get today's USER vote
- update USER vote if he changes his mind (only before 11:00)
- CRUD operations with USER account(register, delete, update, get)
- get USER account with all votes for all time
#####ADMIN-available operations:
- CRUD operations for creating and redacting restaurants
- CRUD operations for creating and redacting dishes for restaurants
- get restaurant (or restaurants) with it's rating for given date. Rating based on count of votes for the restaurant for given date
- CRUD operations for admining users accounts
- get all votes from specified user
- get all votes from specified date
- get all votes for specified restaurant from specified date
Request
GET http://localhost:8080/restaurants/restaurants/withMenu?date=2020-01-30
curl "http://localhost:8080/restaurants/restaurants/withMenu?date=2020-01-30" --user user3@yandex.ru:password3
Response
Request Method: GET
Status Code: 200
Content-Type: application/json
[{"id":100006,"name":"Pizza Hut","dishes":[{"id":100009,"name":"Mexican pizza","cost":999,"date":"2020-01-30"},{"id":100010,"name":"Italian salad","cost":349,"date":"2020-01-30"},{"id":100011,"name":"Cappuccino","cost":199,"date":"2020-01-30"}]}, {"id":100007,"name":"Sushi Roll","dishes":[{"id":100012,"name":"Philadelphia roll","cost":849,"date":"2020-01-30"},{"id":100013,"name":"Fish salad","cost":249,"date":"2020-01-30"},{"id":100014,"name":"Green tea","cost":99,"date":"2020-01-30"}]}, {"id":100008,"name":"Kebab House","dishes":[{"id":100015,"name":"Kebab XXL","cost":1249,"date":"2020-01-30"},{"id":100016,"name":"Garlic sauce","cost":99,"date":"2020-01-30"},{"id":100017,"name":"Beer","cost":399,"date":"2020-01-30"}]}]
Request
POST http://localhost:8080/restaurants/profile/votes?restaurantId=100006
curl -X POST -H "Content-Type: application/json" --user user3@yandex.ru:password3 "http://localhost:8080/restaurants/profile/votes?restaurantId=100006"
Response
Request Method: POST
Status Code: 201
Content-Type: application/json
{"id":100043,"restaurant":null,"voteDate":"***CURRENT DATE***"}
Request
POST http://localhost:8080/restaurants/profile/votes?restaurantId=100006
curl -X POST -H "Content-Type: application/json" --user user4@yandex.ru:password4 "http://localhost:8080/restaurants/profile/votes?restaurantId=100006"
Response
Request Method: POST
Status Code: 422
Content-Type: application/json
{"url":"http://localhost:8080/restaurants/profile/votes","type":"VALIDATION_ERROR","details":["com.natalinstanislav.restaurants.util.exception.VoteDuplicateException: You already voted today! If you want to change your choice, you can do it in special section in your personal account."]}
Request
GET http://localhost:8080/restaurants/profile/votes/today
curl "http://localhost:8080/restaurants/profile/votes/today" --user user0@yandex.ru:password0
Response
Request Method: GET
Status Code: 200
Content-Type: application/json
{"id":100039,"restaurant":{"id":100007,"name":"Sushi Roll","dishes":null},"voteDate":"***CURRENT DATE***"}
Request
PUT http://localhost:8080/restaurants/profile/votes/100039?restaurantId=100006
curl -X PUT -H "Content-Type: application/json" --user user0@yandex.ru:password0 -d '{"id":"100039", "voteDate":"2021-04-10"}' "http://localhost:8080/restaurants/profile/votes/100039?restaurantId=100006"
Response (if current time is BEFORE 11:00)
Request Method: PUT
Status Code: 204
Content-Type: no content
Response (if current time is AFTER 11:00)
Request Method: PUT
Status Code: 422
Content-Type: application/json
{"url":"http://localhost:8080/restaurants/profile/votes/100039","type":"VALIDATION_ERROR","details":["com.natalinstanislav.restaurants.util.exception.TimeValidationException: Can't revote after 11:00"]}
Request
GET http://localhost:8080/restaurants/profile/withVotes
curl "http://localhost:8080/restaurants/profile/withVotes" --user user3@yandex.ru:password3
Response
Request Method: GET
Status Code: 200
Content-Type: application/json
{"id":100003,"name":"User3","email":"user3@yandex.ru","enabled":true,"registered":"2021-04-10T14:22:10.864+00:00","roles":["USER"],"votes":[{"id":100033,"restaurant":{"id":100006,"name":"Pizza Hut","dishes":null},"voteDate":"2020-01-30"},{"id":100037,"restaurant":{"id":100006,"name":"Pizza Hut","dishes":null},"voteDate":"2020-01-31"}]}
Request
GET http://localhost:8080/restaurants/admin/restaurants/100006/withMenu?date=2020-01-30
curl "http://localhost:8080/restaurants/admin/restaurants/100006/withMenu?date=2020-01-30" --user admin@gmail.com:admin
Response
Request Method: GET
Status Code: 200
Content-Type: application/json
{"id":100006,"name":"Pizza Hut","dishes":[{"id":100009,"name":"Mexican pizza","cost":999,"dishDate":"2020-01-30"},{"id":100010,"name":"Italian salad","cost":349,"dishDate":"2020-01-30"},{"id":100011,"name":"Cappuccino","cost":199,"dishDate":"2020-01-30"}]}
Request
GET http://localhost:8080/restaurants/admin/restaurants/100006/withMenuAndRating?date=2020-01-30
curl "http://localhost:8080/restaurants/admin/restaurants/100006/withMenuAndRating?date=2020-01-30" --user admin@gmail.com:admin
Response
Request Method: GET
Status Code: 200
Content-Type: application/json
{"id":100006,"name":"Pizza Hut","dishes":[{"id":100009,"name":"Mexican pizza","cost":999,"dishDate":"2020-01-30"},{"id":100010,"name":"Italian salad","cost":349,"dishDate":"2020-01-30"},{"id":100011,"name":"Cappuccino","cost":199,"dishDate":"2020-01-30"}],"rating":3}
Request
POST http://localhost:8080/restaurants/admin/restaurants
curl -X POST -H "Content-Type: application/json" --user admin@gmail.com:admin -d '{"id":null, "name":"NewRestaurant"}' "http://localhost:8080/restaurants/admin/restaurants"
Response
Request Method: POST
Status Code: 201
Content-Type: application/json
{"id":100043,"name":"NewRestaurant"}
Request
DELETE http://localhost:8080/restaurants/admin/dishes/100009
curl -X DELETE -H "Accept: application/json" --user admin@gmail.com:admin "http://localhost:8080/restaurants/admin/dishes/100009"
Response
Request Method: DELETE
Status Code: 204
Content-Type: no content
Request
GET http://localhost:8080/restaurants/admin/votes/byDate?date=2020-01-30
curl "http://localhost:8080/restaurants/admin/votes/byDate?date=2020-01-30" --user admin@gmail.com:admin
Response
Request Method: GET
Status Code: 200
Content-Type: application/json
[{"id":100030,"restaurant":{"id":100006,"name":"Pizza Hut","dishes":null},"voteDate":"2020-01-30"},{"id":100031,"restaurant":{"id":100008,"name":"Kebab House","dishes":null},"voteDate":"2020-01-30"},{"id":100032,"restaurant":{"id":100008,"name":"Kebab House","dishes":null},"voteDate":"2020-01-30"},{"id":100033,"restaurant":{"id":100006,"name":"Pizza Hut","dishes":null},"voteDate":"2020-01-30"},{"id":100034,"restaurant":{"id":100006,"name":"Pizza Hut","dishes":null},"voteDate":"2020-01-30"},{"id":100035,"restaurant":{"id":100007,"name":"Sushi Roll","dishes":null},"voteDate":"2020-01-30"}]