I am currently building ServerlessQ on the side. It is a hosted message queue service for Vercel users to build proper asynchronous systems.
This post gives an update on the current progress. I'll introduce a first glance at the dashboard. The dashboard is the main interaction point with the production.
The UI is far from finished but I think you get a good idea of the product.
The dashboard will be available under the domain: app.serverlessq.com
It is the main interaction point with the product. You can do the following things:
First of all, you can create a queue. After creating a queue you'll get an URL to which to send your requests to. All requests sent to this queue will be forwarded to your defined target in your request.
The dashboard also gives you an overview of your sent requests and their responses.
The goal is to give users the ability for a nice overview of all requests and their properties like status, headers, bodies, and retries.
It is also possible to send messages directly from the UI. With that, it is easy to get started and understand the product without leaving the system. In a productive setting, messages won't be sent from the UI of course and code will be used. But to test it out it is easier to mock the send message functionality from the UI.
These are the main use cases that are already working. Let's have a look at them in the prototype.
Let's have a look at the prototype dashboard.
First, let's create a queue.
https://giphy.com/gifs/OOiM602lK6DCwfaqLJ
It is a simple form with the attribute name. When you click on Create Queue several things happen. I showed them in detail in my first blog postof this series.

EventSourceMapping will be created and attached to a lambda function which executes the requestsqueuesThat's it for creating a queue.
Next, we have a list of queues. For now, we have some simple cards which show the name of the queue and the URL to your request that needs to be sent.

Next to the link, there is a simple copy link to copy the link with the URL straight to your clipboard.
The implementation is pretty straightforward. All queues are saved in DynamoDB with attributes like:
We've got an index on this tablebyUser. This index has the pk of userId. With that, we're able to query all queues by a user.

We then go ahead and call the query:
query ListAllQueues($userId: ID!) {
getQueuesByUser(userId: $userId) {
arn
createdAt
id
name
sqsUrl
updatedAt
status
}
}
The query will be resolved by VTL resolver:
queueDataSource.createResolver({
typeName: 'Query',
fieldName: 'getQueuesByUser',
requestMappingTemplate: appsync.MappingTemplate.dynamoDbQuery(
KeyCondition.eq('userId', 'userId'),
'byUser'
),
responseMappingTemplate: appsync.MappingTemplate.dynamoDbResultList()
});
By clicking on one queue, you will see three main things.

Metadata
The metadata should simply give you some basic information about your queue. For now, it is only the URL. More parameters will be added here in the future like custom parameters (timeouts, retries, delays, etc.).

Sending Requests
In the second pane you see the button Send a Message.
This is included to allow users to send a simple message directly from the UI. If you click this button a drawer opens on the right side with a form to send a message.

Here we can define a target API (e.g. your Vercel Function), a method (GET, POST, PUT, etc.), custom headers, and a body.
If you hit Send your call will be forwarded to your queue and finally to your target.
You can then see a live update of your messages on the same page. You can see more examples soon.
👇🏽
Overview of your messages
After sending messages you will see your messages in the overview table.

You get a live update of new arriving messages thanks to AppSync subscriptions 🚀
A message has several attributes. Mainly it is a request. A response is attached if the request was successful and no error on the request level happened. For example, if you try calling an API that doesn't exist you won't get a response because there is no server to respond.
Other attributes are:
All responses (depending on the retries) will be available in the message detail.
For example, if we send a message to the Pokemon API we will see that the request runs through and gives us a status code Success. If we click on the request we see the response with the body of the API. Here we can see all the different details about the Pokemon Ditto.
In contrast, if we send a message and receive an error on the request or response side the queue will retry the message up to a certain threshold. For the MVP this threshold is five but it can be easily customized.
Message Detail
You can also open a message and see the details of that message.
The details have the request and the response view. Both contain the following attributes:
For example the successful Pokemon API call request

And the response:

Let's see it in a GIF⚡️
https://giphy.com/gifs/o2ieLteBzxq4UveD9l
For successful responses, we only get one response. In case of retries, we will see several responses.

Now I'll show you some more examples in quick videos to get an understanding of what is currently working.
I've got one application running on Vercel with a mock API. The mock API simply sends a response with the code 200 and a message.
Vercel Function:
https://www.loom.com/share/c8bb009df0de4f459067a4b92b3a3470
As you can see I forward the message and after the first successful try I'll get a proper response
Now we will mock response errors.
We need to distinguish between response and request errors.
There is a great API out there that simply mocks response error codes. The API is https://mock.codes/. You simply attach a code at the end and this is what the API will return
So if you send a request to https://mock.codes/200 -> You will get a response code of 200.
But if you send a request to https://mock.codes/401 -> You will get a response code 401.
All error codes that are not successful (i.e. >200) will be retried automatically five times. This can be customized in the future.
Let's see how that goes.
https://www.loom.com/share/ba3976ba934c4b4a8ea8c2c8f56389d0
As you can see the retry process is automatically happening and you see the retries counting up.
Here the retries are pretty fast. This can be customized in the future. We want to offer options like:
The last one is simply a request error where we cannot find the URL.
https://www.loom.com/share/efbce6eee02946ed8105e276e31d0196
Here we try to send our request to some API that is not reachable. That is when we show the message AddressDoesntExist. We need to work on the error messages a bit.
We still retry it to have consistent retries on errors.
The next steps are:
Usage Tokens
We need the functionality of using API keys and associating usage plans for each key. The usage plan depends on the subscription the user has.
This will be implemented with:
Redirection
Currently, all calls are made directly to the API GW Stage URL. We want to use our domain for that of course, so we will forward the domain api.serverlessq.com to our stage URL.
UI
We are not settled on the UI yet. We need to change quite a lot here 🙂
Pricing
Connecting pricing + and usage plans with Stripe.
That's it! In summary, the functionality of the MVP stands and is possible to execute from the UI. We are super happy with the progress and we see a lot of potential here.
Quite a lot of things still need to implement but it is amazing what you can build on AWS.
If you're interested sign up for our waiting list here. Or DM me if you're interested in joining as a beta user.
I'd love to hear your feedback so let me know what you think 🙂
Thanks for reading!