Food is not only a primary necessity, but carries culture, history and a lot of research. We are passionate about food, we love to prepare our own meals and to taste new flavours in local festivals, that here in Italy are so frequent and sweet. Above all, we love to visit motorcycle fairs and beer fairs, and the problems are always the same: you are hungry and you have to choose between a large number of food trucks (that is good!) with huge wait lines (that is bad), make a line for food, another line for drinks, and finally search for a table or consume your food nearly cold standing up with the motorcycle helmet in one hand.
So we thought: how can we improve the experience both for the customers and for the food trucks? As a customer, i would like to:
- have a complete menu with prices in my hand, without running from a truck to another;
- do not wait in line, i would prefer to continue visiting the fair or search a calm spot where to eat;
- pay electronically, i would prefer using the payment gateway of the vendor of my phone, like Apple Pay or Google Pay;
- use a web app, because i don’t want to install a new app on my smartphone;
- don’t create another account for this service, just let me order my food please, and don’t ask me to agree for the cookies.
As a food truck manager i would like to:
- not manage cash to avoid human errors;
- have an ordered list of orders, with an easy way to manage quantities for group ordinations.
For both of them, i would like to see a fast application with real time updates.
Bonus: in these times of social distancing, every technology that eases the return to a normal life with the necessary distance between humans permits to have happy customers (that will buy from the food truck with confidence) and happy truck managers (that don’t have to vigilate on the distance between the persons waiting in line).
What it does
Starting from these user stories, we have conceived Slurpanize, a white-label platform that is a meeting point between the needs for more comfort by the customers, and for more control by the truck managers.
It serves the customers giving them an easy and private way to interact: there is no need to install another app or create another account, because the user is managed by a Telegram bot. With the help of the bot, the customer reaches the menu page, selects what to buy spawning between multiple food trucks, pays with his smartphone in the chat and waits the notifications by the different food trucks that update the order status.
Our attention points for the user have been:
- Give the user the right tool for the right action to do. The Telegram bot serves as an entry point to aknowledge the user, then he is redirected to a web application that is the right medium to display and manage complex information like long lists, researches and user actions. At the moment of the confirmation of the order there is no more the need of a complex interface, and the user is seamlessy redirected to the Telegram bot that will handle the payment. The bot continue to be useful providing the notification channel between the users and the trucks;
- Reactivity and fastness. The Quarkus framework is the right choice to achieve a really fast and robust backend;
- Officiality. The user never knows about “Slurpanize” because he sees only the name of the fair (or the food truck) that he is visiting. Our platform is deployed on Kubernetes, and we can create one environment for each festival or truck, giving them a tool to be more recognizable for their customers.
By the side of food trucks, Slurpanize gives a web dashboard with every order, its status and the actions to do to notify the users about every change. The food truck managers can have multiple smartphones and tablets at their service (for example, one for the kitchen side and one for the cash desk), and every terminal presents the updated status, thanks to real time messages streamed by the server. The food trucks will receive orders displaying them on their dashboard, knowing that they are already paid, pack the order notifying the customer that the preparation is ongoing, and finally hand over the order to the customer.
Our attention points for the food trucks have been:
- Real time updates. If the truck managers need more terminals to manage their orders, they can have! We have used the Stomp protocol to dispatch real time messages between the clients.
- Orders’ organization. The dashboard is divided to display the orders by their status, so that who delivers the orders to the customers sees only the orders ready to be delivered.
- Payment management. The trucks don’t need to handle cash, because is all managed by the bot, speeding the order process and avoiding human errors.
- Festival or single truck? Both! We have created a system that can be used by a festival (that is a group of trucks) or by a single truck.
How we built it
The entire backend project is built on top on the latest versions of these libraries and frameworks:
- The Quarkus framework is the core of the project;
- Telegram bot library offers an abstraction layer from the basic Telegram communication protocol and messages;
- Artemis ActiveMQ for delivering messages into the application and dispatching them via websocket;
- Kubernetes works as abstraction layer and deployment system;
- GitLab is used not only as project repository, but also for automatically-built docker images for being hosted on the kubernetes cluster;
- PostgreSQL with reactive drivers for data storage.
The main purpose of the application requires that the backend reacts to each user input in no-time. This goal is reachable by using the main characteristics of Quarkus framework: reactivity and asynchronicity.
The architecture of Slurpanize Backend Services project is divided into two main parts:
- Rest API part: serves the data to the web application giving and transforming them from the database or external interactions;
- Reactive messaging: uses event bus, SmallRye reactive messages and websocket to give to the users real-time feedback about what happens to their orders.
The RestAPI application follows these steps to reach the goal:
- a controller's endpoint receives an HTTP call from the frontend application;
- transforms this request in an Uni or Multi object of the Mutiny reactivity stream;
- the reactive object built above fires the "on-item" event. This is linked to a public method in its service class (because the project is structured to have a service that accomplishes a specific task);
- the service is a collection of functions that interact with the database in a sort of chain of functions. This chain is built in a sequence of callbacks that are called with then methods available by Mutiny structure;
- once the chain finishes its task, the main method of the service maps the data in the object ready for being transformed into a JSON that is sent as response from the action's controller.
These steps use the Mutiny functions chaining: in this way is possible to call various steps without blocking the process.
The other part of the project uses reactive streams in different forms and approaches:
- in memory vertx eventBus is being used for streaming data between beans: in this way is possible to call various parts of code without injecting beans or is possible to emit same event that fires parallel tasks. For example, eventBus message is used for sending a message with Telegram's Bot and, in the same time, the merchant receives the status update in its back-office dashboard;
- SmallRye reactive messages, in combination with ActiveMQ, reacts to orders' change status and streams data in WebSockets;
- WebSockets are used for streaming data to back-office portals that merchants use for managing the orders.
The choice of Artemis ActiveMQ has been lead by accomplishing the data knowledge sharing between PODs in Kubernetes cluster.
Having the application deployed on multiple pods generates a problem of connection between the client web app and the PODs: if there are multiple clients, is probable that they are not connected to the same pod, they will not share the same channel for the fired events, and this generates a missing passage of information if a simple websocket is used.
Instead with the introduction of ActiveMQ, when a merchant changes an order status, the frontend calls a POD in Kubernetes, this POD writes the change into database, then streams a ChangeOrderStatusEvent into a queue for sharing the status change between available PODs. If a merchant uses two or more terminals for managing the orders the fact that the same message is streamed in a common line of communication permits to deliver the same message via all available PODs. Moreover, the ActiveMQ permits to dispatch a message using a queue that is fed by Slurpanize backend and consumed from the front-end application in form of Websocket (Stomp).
The application is built and delivered using classical DevOps pipeline that guarantees an efficient approach to application's deliver and testing.
In this process are involved these components:
- Gitflow workflow: an approach where main git branch is used for delivering production-ready code with tags;
- GitLab for versioning, building, and delivering the code; also is used as docker image registry;
- Kubernetes Cluster to host, execute and manage the containers.
The scaffolded Dockerfile by Quarkus project generator is being modified to be executed in docker-in-docker (DIND) environment. This permits to deliver Quarkus code in a GitLab pipeline. The build process is composed by these steps:
- DIND environment is enabled by GitLab;
- openJDK container image is used for building the "build image" where the project is being compiled;
- into the previous image the project is compiled by using the native maven wrapper command;
- the target image is built for hosting the services and uses the standard Dockerfile processes established by project scaffold;
- the code built in "build image" is copied into target docker image;
- the image is pushed in GitLab docker image registry.
Challenges we ran into
The project reserved us three major challenges:
- we had an initial idea that we had to change because of the lack of time to develop that idea;
- we had to try different protocols to manage the real time websocket, consuming some precious time;
- We changed the frontend framework during the development because we needed more flexibility.
As persons and as developers, we believe that there are no problems but only opportunities, and managed to solve our challenges with constant collaboration and mutual support. We never talk about “wasted time”, because, as Edison, now we know how to not code things :)
Accomplishments that we're proud of
We are really proud of the system we developed to incorporate the build process into the pipeline with the use of Docker-in-docker. Despite of the lack of online documentation, we succeeded to integrate a real time protocol (in this case ActiveMQ with Stomp) and taking advantage of its interoperability functions. We have strengthened the knowledge of Quarkus taking advantage of the reactivity and the event management, developing an highly maintainable code.
We enjoyed every single moment of the development, including 3 weeks of sleepless nights :)
What we learned
This is not our first hackathon and we are experienced developers, but we find always something new to learn:
- on the development side, Erika has developed for her first time a React application with hooks, and Davide deepened his knowledge of Quarkus and the DevOps side of it;
- on the documentation side, we know that to grow in our career as developers we have to exercise a lot in the explanation of our ideas and projects, and we have taken the chance of this project to provide a good documentation.
What's next for Slurpanize
Having done some market researches in some local activities and knowing that the idea is evaluable for their business, the next steps for Slurpanize are:
- to develop the merchant back office. We have only developed the managing order backoffice for the sake of demonstrating the framework capabilities, but we have to add the login part, the menu management, and the automatic provisioning of the application for the new merchants;
- to review the UI with an expert. We already know that as developers is terribly hard to conceive the UI of an application, so we know for sure that we have made mistakes
- to add more functionalities. We would like to add the waiting time to have the order prepared, to manage the internationalization and localization, and to take advantage of the Telegram bot functionality to start the bot sharing an invoice.