We will approach microservices by implementing a really simplistic messaging environment where users (or applications) can log onto a service and then post messages to channels and retrieve the newest messages on a specific channels. One can also list the available channels and create new channels. We keep it simple in that everyone can create new channels and for now we won't delete any channel. The last 100 messages for each channel will be kept in memory. This no WhatsApp but we will at the end use any server developed in any of the languages here and connect with clients from all the other languages. We will be using normal HTTP for our comms and we will use JSON for our queries and the results.
NB: Please note that the programming examples focus more on how microservices could be implemented in the various languages than on best practices in these languages or a full blown implementation. You can obviously take it further to do just that if you want. In some cases libraries already exists to do similar stuff in the various languages but we just want to demonstrate how one would go about developing microservices from scratch.
The calls to the microservice server will be the following:
While we use HTTP as our comms medium we will put the function name in the url of the request, the rest of the data will be in the body of the POST.
We will not make use of the REST Services approach by using GET, DELETE, POST and UPDATE. We will only use POST and put the data in the body of the call.
Please remember that the idea is that each client irrespective of programming language will be able to call services from any of the servers irrespective of programming language.
A basic template for a function call (except logon) will be as follows:
{ "sesskey": the-numeric-key-of-the-session, ...... }
The sesskey is the result returned by a successful logon and
all calls must use it and the call can only be successful if it is a valid session key and have not expired.
The rest of the data then follows the sesskey.
In all of the cases a failure will result in the following JSON to be returned:
{ "status": false, "data": "the reason why logon failed" }
A successful call will return JSON that will look as follows:
{ "status": true, "data": actual-data }
Where data will vary according to the actual information returned.
For each of the calls we will have the following JSON call and result structures:
logon |
CallPOST /logon{ "username": "the name of the user", "password": "the password of the user" } Success Result{ "status": true, "data": the-numeric-key-of-the-session } |
logoff | CallPOST /logoff{ "sesskey": the-numeric-key-of-the-session } Success Result{ "status": true, "data": true }Seeing that there really is no data we are only returning true (this just makes it easier for now with unmarshalling JSON in some of the programming languages) |
list |
CallPOST /list{ "sesskey": the-numeric-key-of-the-session} No data is needed for asking for a list of channels. Success Result{ "status": true, "data": [list of channel names] } |
create |
CallPOST /create{ "sesskey": the-numeric-key-of-the-session, "channel": "channel name" } Success Result{ "status": true, "data": true } |
post |
CallPOST /post{ "sesskey": the-numeric-key-of-the-session, "channel": "channel name", "message": "the message to post to the channel"} Success Result{ "status": true, "data": true } |
lastmessage |
CallPOST /lastmessage{ "sesskey": the-numeric-key-of-the-session, "channel": "channel name" } The last message that we've seen can be different than what is in the server seeing that other clients could have posted messages to the channel. Thus to retrieve only the latest messages we would request messages up to the last one. Success Result{ "status": true, "data": the-message-id-of-the-last-message } |
retrieve |
CallPOST /retrieve{ "sesskey": the-numeric-key-of-the-session, "channel": "channel name", "first": message-id-of-first-message, "last": message-id-of-last-message } Success Result{ "status": true, "data": [{"messageid": messageid, "username": "name of poster", "message": "the message text"}, ....] } |