In the old days of software development, an application was developed on a server and sold to a customer in a box, which they then ran on their computer. The developer provided support and issued software patches online. This was a software product, what we now call a monolithic application.
As web development grew, software become increasingly de-coupled from the physical world. Engineers could collaborate with Git. Virtual machines could run within remote machines. RESTful APIs offered stateless, secure, and standardized connections between clients and servers. The final nail in the coffin was containerization, where Docker and Kubernetes clusters could be deployed anywhere, with minimum overhead. This allows applications to be "written once and run anywhere."
This has fundamentally changed what an application is. Microservices are an application, but broken into many pieces across the cloud. It is an application as a sum of its connections, instead of one piece of software sold in a box. This is called "microservices architecture," vs the old way of "monolithic architecture."
We're starting a sock shop. We do one thing, and we do it well. In the old days, we'd put socks in a box, go to the swap meet, and hawk our wares. In the 90s, we'd code a website that lived on a server. Now, we'll have our development team make a few REST API calls to existing services via an API gateway, perform some technical orchestration, and have our socks shop. What functionality might our sock shop need to flourish online? We need a landing page, a catalogue of our socks, an inventory system, a secure payment system, and customer service. Now, we could write a bunch of custom code and build all this stuff ourselves, but looking around the internet, we see a whole lot of e-commerce sites that look like they work just fine. Why not re-use what already works in a service-oriented architecture? We break the parts down into individual services- microservices- like payment, catalogue, and inventory, and spin them up as containers in the cloud. A container is an application with its runtime requirements included in the package.
It is like a virtual machine, but much more lightweight. We then use an API gateway to orchestrate all of these services into a distributed system, and accept requests from the front-end client. This part requires rigorous engineering to reduce round trips, decrease latency, and increase API security at public-facing endpoints. It will also require API testing to ensure all of our microservices are operating as a team with load balancing, continuous integration, and continuous delivery. Once we're done, we will have our online sock shop, with minimal creation of new code on our part. We've just used what already works, and made it work in harmony. It'd probably look like this.
Microservices encourage decoupling, agility, and scalability. Each microservice can be owned by one development team, and can scale independently. Teams can take advantage of several patterns such as event-driven programming and autoscale scenarios, where one service might need more resources than usual. They can be technical to orchestrate, but the road away from the monolith architectural style is a fruitful one.