Suppose that I have a UserService in my Microservice Architecture deployed on the cloud. There is a Service Discovery for routing the requests to different host of UserService.
If I have two different versions of UserService. Lets say user-service-1.0 and user-service-2.0 and part of clients should still use older version, then how this can be managed in Microservice Architecture.
For backward compatibility, see Product Versioning Microservices, in general Semantic Versioning is advised by many...
In the broader sense - there should be an agreed phase-out roadmap for major versions, that is communicated to API consumers (together with SLAs). This is why tracking who uses your APIs is important.
Every version of UserService needs to be backwards and forwards compatible. This way clients can talk to any version of the service and not crash.
Of course, the details of how this is achieved depends on your architecture.
Related
Why not just make your backend api route start with /api?
Why do we want to have the /v1 bit? Why not just api/? Can you give a concrete example? What are the benefits of either?
One of the major challenges surrounding exposing services is handling updates to the API contract. Clients may not want to update their applications when the API changes, so a versioning strategy becomes crucial. A versioning strategy allows clients to continue using the existing REST API and migrate their applications to the newer API when they are ready.
There are four common ways to version a REST API.
Versioning through URI Path
http://www.example.com/api/1/products
REST API versioning through the URI path
One way to version a REST API is to include the version number in the URI path.
xMatters uses this strategy, and so do DevOps teams at Facebook, Twitter, Airbnb, and many more.
The internal version of the API uses the 1.2.3 format, so it looks as follows:
MAJOR.MINOR.PATCH
Major version: The version used in the URI and denotes breaking changes to the API. Internally, a new major version implies creating a new API and the version number is used to route to the correct host.
Minor and Patch versions: These are transparent to the client and used internally for backward-compatible updates. They are usually communicated in change logs to inform clients about a new functionality or a bug fix.
This solution often uses URI routing to point to a specific version of the API. Because cache keys (in this situation URIs) are changed by version, clients can easily cache resources. When a new version of the REST API is released, it is perceived as a new entry in the cache.
Pros: Clients can cache resources easily
Cons: This solution has a pretty big footprint in the code base as introducing breaking changes implies branching the entire API
Ref: https://www.xmatters.com/blog/blog-four-rest-api-versioning-strategies/#:~:text=Clients%20may%20not%20want%20to,API%20when%20they%20are%20ready.
I have a usecase where I have to collect user events and store it in Kafka. Is it efficient to directly use Kafka clients in mobile apps and websites to produce messages directly to Kafka instead of a middle layer. Is Kafka designed to handle millions of concurrent connections?
Technically you can do it. The main reason people do not do it, especially for mobile apps, is that it would rather be difficult to maintain a long-term evolution of the product, control its security or even its scale.
In the past years, Kafka Clients API has evolved dramatically (for the best but, it's still a change). It also includes authorization and authentication mechanisms, but there's not much freedom on what you can do with those. Kafka is not built upon a standardized protocol and technology-agnostic specification like JMS that could be thought as a bit more flexible.
Also, between major versions, compatibility is not guaranteed, as for most existing technologies. It may happen that you need to keep multiple server versions for a long time just because some mobile clients are still outdated and there's coupling to a specific client version, that itself is coupled to a specific server version.
On the other side and for the same reason, it could also happen that you would need to keep handling older versions of the messages schemas for a long time, just to keep older clients happy.
That's when HTTP and, more specifically, the API gateway pattern, comes into place.
HTTP APIs are easier to throttle, perform rate limiting, applying custom security policies, custom authentication/authorization strategies, etc. And they are based on a standard protocol that's used all over the Internet.
There are also advantages of using HTTP when you plan to have some partner integrations using your backend platform. As they can do it easily without changing the technology stack.
By not exposing Kafka to the outside clients, you can change the underlying technology stack later without impacting the clients. To be honest, although Kafka is a brilliant piece of technology, it's difficult to compete with HTTP for internet communication. Kafka actually provides a REST Proxy, an HTTP based client that could be possibly thought to be used for this sort of things.
I am learning about microservices and I don't understand what the real difference
between creating a REST API and creating microservices?
I’m working in Go, but my question applies over all languages.
The Microservices approach is about breaking your system ("pile of code") into many small services, each typically has its own:
Clear business-related responsibility
Running process
Database
Code version control (e.g. git) repository
API (the protocol how other services / clients will contact the Microservice)
UI
The services themselves are kept small so as your system grow, there are more services - rather than larger services.
Microservices can use REST, RPC, or any other method to communicate with one another, so REST or an API is really orthogonal to the topic of microservices...
Reference: What is an API? In English, please.
API = Application Programming Interface
Microservices = an architecture
In short
Microservice should expose a well-defined API.
Microservice is the way you may want to architect your solution
API is what your consumers see.
You can expose API without microservices in the backend (in fact, most non-training scenarios don't require microservices).
You may want to read http://samnewman.io/books/building_microservices/ before you decide on using microservices (unless this is for training purposes).
Microservice is well defined when you are following SOC - seperation of Concern on the entity/domain level ,where each entity / domain are independent of any other service.
for example user service will only be responsible for storing, updating and deleting user related informations.
Microservice backend and frontend microservice can further be splitted in 2 parts
frontend microservice which exposes rest endpoint just like Web API
backend microservice which actually perform all the operations.
Rest API is more of endpoints exposed to outer world and can be used with microservices as well, as explained above.
The majority of the answers is based on the old-school understanding of API as a programmatic interface. Nowadays, this meaning is melted and start confusing people becuase some developers started (for simplicit or by mistake) interpred the API of an application as the application per se. In such case, it is impossible to distinguish between the modern API and Microservices. Nonetheless, we can say that an API-application can comprise many Microservices, the most of which interact within the application via Microservice's APIs while others may expose their APIs as Applications's APIs. Also, a Microservice (as a service) may not include other Microservices (services), but may orchestrate a composition of Microservices via API-bases invocations. Applications may contain Microservices but, in the best practices, may not contain other Applications.
Microservices
A microservice architecture is about slicing an application logic into small pieces or "components" that can act between them and/or be exposed through an API.
API
A (web) application need to design the business logic with all set of object entities (model) and possible operations on them.
An (Application Programming Interface][https://en.wikipedia.org/wiki/Application_programming_interface) is a way of making the requests to an application by exposing specific entry-points that are in charge of invoking the appropriate application operations.
ReST(ful) APIs
("ReST" as in Representational State Transfer) are APIs complying with at least these 5 constraints:
User-interface is distinct from data storage and manipulation (Client-Server architecture)
No client context is stored on the server ("stateless")
Server responses must, implicitly or explicitly, define themselves as cacheable or not
Client does not have to be aware of the layers between him and the server
Response/request messages must be: be self-descriptive; allow to identify a resource; use representations allowing to manipulate the resources; announce available actions and resources ("Uniform interface").
"The real difference"
So, while these notions are obviously related, they are clearly distinct concepts:
Being ReSTful or not, an API exposes operations provided by a server that might (but not necessarily) be shelled into smaller components (microservices).
Also, while a typical web (ReST)API uses the HTTP protocol between the client and the server, components within a microservice architecture might communicate using other protocol(s) (e.g. WAMP, AMQP, JSON-RPC, XML-RPC, SOAP, ...)
In layman's term, if you have a web API server and you split them into several independent mini servers, use a proxy-server and load-balancer to clusterize them, and (optionally, give each a separate database entity), that is a microservice architecture.
I have a microService architecture with 10 microServices and each of those provides a client. Inside of that client which is managed/controlled by microService team we just receive the parameters and pass them to a generic http invoker which receives the endpoint and N params and then does the call.
All microService use http and web api (I guess technology doesn't matter).
For me doesn't make sense to be the microService team to provide a client, should be the responsibility of the consumer, if they want to create some abstractions or invoke it directly is their problem, not a microService problem. And the way I see a web API is as a contract. So I think we should delete all clients (pass responsibility to consumers) on the microService side and create a service layer on the consumer's side that uses the generic invoker to reach the endpoints.
The image below represents all components where the red line defines the boundaries, who is responsible for what:
The gateway has Adapter Layer
Adapter Layer references the microService client package
MicroService client package references Generic HTTP invoker package
The other side of that is because we might have N number of consumers and they are all repeating the code of the client. And if the microService provides a client, we have a unique/central place to control that.
Which approach is correct? Is the client a responsability of the microService or the consumer?
This is an internal product.
I have a similar setup at work, with several microservices (~40) and a dozen teams. I was asked the same question several times, and my answer is the consumer is responsible for consuming. If the API works as designed and expected, there is no point in making the providing team responsible for anything.
The team that provides the service (team a), may provide a client, if they want (in doubt, without warranty). The consuming team (team B) may use the client if they want (taking all the risks included).
The only contract should be the API, everything else should be a goodie a team may provide on top. If team a has to provide a client, why do they provide an api at all then?
Given that both teams are loosely coupled and may use different technologies (or e.g. different spring framework versions), providing a client library to the other team proves to bring more problems than solve any. In a Java+spring-boot world e.g. you get into dependency problems very fast, especially if you include several clients from different service providing teams that evolve differently in time.
And even worse: what if the client-library of team A makes the system of team B unstable and introduces bugs? Who is responsible to fix that now?
If you want to reduce the work needed for your consuming teams because re-coding the client is so much work, your API may be to complex and/or your microservice may be no more microservice at all.
Imagine using HATEOAS on a restful API - writing a client for that is just a few lines of code, even with included API-Browser, Documentation and whatnot. See e.g. spring-rest-docs, hal-browser, swagger and various other technologies that make reading/browsing/documenting an API and implementing a client a breeze.
Above cases are described with two teams, imagine that with 10. We had a "client library" provided by one team, used by 4 other teams. You can guess how fast it became a complete mess until it was just deleted :)
We are using Akka as our microservice platform. We are not going to support non-JVM platforms for now, so we use direct messaging between Akka actors as communication platform.
This way, our communication units are just case classes. Do we have to repeat ourselves and define the case classes for each microservice or we can put all message classes into a single project and share it between microservice projects?
I know that sharing models between microservices is not recommended but as we use Akka communication protocol, I'm not sure if creating the same communication case class in multiple projects is correct. What if a microservice change it's model and the others don't? How can we handle versioning and upgrade to new versions of the communication models without breaking the whole system.
One possible solution is building each microservice as few packages and handle versioning by SBT:
model - set of classes divided between microservices
core - microservice logic, depends on model package
gateway - interface to main microservice, depends on model package, included by other microservices, it is possible to cache some info here