This maybe a little of topic introduction, but for your own favor, please don't implement microservices pattern if you don't have a proper use case. Otherwise you will suffer. :)
For the communication part, you can use REST APIs and sockets. Leveraging REST is rather easy. But If you don't have experience in sockets and more importantly your framework of choice doesn't have prebuilt libraries for leveraging sockets it can be problematic. Sockets are less expensive than REST APIs.
And offcourse you can use messaging queues for async communication.
Learning CQRS can help you a lot with microservices.
Command and Query are general operations we use when developing software.
Consider this task: Update status of the user with the ID 5 and send an email regarding the update.
There are three operations in this task can be simplified as follows:
Where 1 is a query and 2 and 3 are commands. Queries are mostly sync where commands are async. So first item should be in sync because you are querying some service and you want to hear back from the service with the details of the user.
For the first item we can create a query. Like this.
class FetchUserById
{
protected int userId;
constuctor(int userId) {
this.userId = userId;
}
}
Message bus is used to serialize the message (above) and send it to related source via your transport of choice. You can choose REST, Socket (which will be synchronous) or amqp to have async behaviour.
Operation 2 and 3 can be async, so we can utilize appropriate messaging bus that uses amqp as transport.