I started learning Rust last week. I finished a course on Udemy on Rust (3-4days), read the rust-docs (in part), Rocket docs (in full) and docs of various other crates as required.
This is my first project in Rust. I found Rust very interesting, it made me think a lot more about WHY, at every step, instead of HOW and reminds me of C++ days.
The concepts of trait implementation, lifetime, ownership, borrowing(!), Arc/Rc/RfCell/Mutex etc. are still volatile in my memory,
but I have tried my best to put up something (with sufficient tests), in a limited time.
There would surely be places where snippets could be a bit more concise and 'functional' if I was more accustomed to Rust's huge repertoire of higher-order functions. But, I'm sure to have a grasp on those in time, just like any other languages.
- Since the problem statement doesn't mention data needs to be stored
on-diskpersistently, I am assuming an on-memory db, or a thread-safe data-structure is fine.
Please check the API_SPEC.md for API specification.
rustup toolchain install nightly
rustup default nightly
(Inside project root directory, run the following commands)
cargo build
cargo test
cargo run
(Since, the worker threads are run on application start, there would be lots of logs being written.)
(Run tests that require application to be running)
cargo test -- --ignored
(To create docs, run)
cargo doc --no-deps --target-dir docs
Note: After
cargo run, if there is an error similar to"An established connection was aborted by the software in your host machine.", please run the application using IDE (e.g. IntelliJ IDEA).
To know more about this error, see here.
A quick solution might be settingRocket.toml>[development]>addressto"127.0.0.1"
- Load the POSTMAN collection from here in your POSTMAN client using
import. - Make sure API is running on
localhost:8000. - Send a
GET /menusrequest to load menus. The postman collection uses environment variable. - Send a
POST /ordersrequest to create an order. - Then try other Requests as you like.
PUT /configsets table_count. If you seeInvalid table selection.error inPOST /ordersrequest, use this to settable_count.
worker.rs uses 10 threads to make parallel async API calls with randomly selected data.
The clients are started automatically at application start. Check Terminal/IDE logs to verify output.
Method mentioned below belongs to logic.rs
- The client (the restaurant staff “devices” making the requests) MUST be able to: add one or more items with a table number, remove an item for a table, and query the items still remaining for a table.
Use
create_order(),delete_order(),get_remaining_orders()
- The application MUST, upon creation request, store the item, the table number, and how long the item will take to cook.
Use
create_order()to store all these info plus alpha (see Order struct in models.rs). For multiple order items, call multiple times (each "order" resource can have only one item by design, for "order" to be used as message in downstream pipeline). Useget_remaining_orders()to get all remaining orders. Calculate time-to-serve using (estimated_serve_time - now) at client-side. (See worker.rs)
- The application MUST, upon deletion request, remove a specified item for a specified table number.
Use
get_remaining_orders()to fetch ordered items bytable_id. Then usedelete_order()to CANCEL any un-served order.
- The application MUST, upon query request, show all items for a specified table number.
Use
get_orders_by_table()to fetch all orders bytable_id. Using filter such as?state="ORDERED"is advised.
- The application MUST, upon query request, show a specified item for a specified table number.
Use
get_orders_by_table()to fetch all orders bytable_id. Then useget_order()to GET a specific order.
- The application MUST accept at least 10 simultaneous incoming add/remove/query requests.
Change
THREAD_COUNTin worker.rs to increase/decrease client thread count (within limitation of heap/stack size).
- The client MAY limit the number of specific tables in its requests to a finite set (at least 100).
Use
set_table_count(). Check format ofConfiginmodels.rs.
- The application MAY assign a length of time for the item to prepare as a random time between 5-15 minutes.
preparation_timefor each menu item is set while creating the menu. Checkmenu.json.
- The application MAY keep the length of time for the item to prepare static (in other words, the time does not have to be counted down in real time, only upon item creation and then removed with the item upon item deletion).
It's kept static. Use
get_remaining_orders()to fetch remaining orders and Calculate time-to-serve using (estimated_serve_time - now) at client-side. (See worker.rs)
- Error-handling
- Documentation: Docs pages are mounted on http://localhost:8000/simple_restaurant_api/ (if you had run
cargo doc) - Request format validation
- Any type of security features
- API support for
Content-Typeother thanapplication/json - While creating resources, although using UUID as
id, have not implemented checks for rare but possible id-collision. When using a real DB such occurrences will throw an error from the DB and API/logic can retry with a new UUID.
- Use a Database to persist data on disk.
- Use Diesel for ORM.
- Add authentication.
- Add CORS support (using
rocket_corsor fairing).