Configure downstream API endpoints in microservices - api

In a microservice world, what is the recommended way of configuring the endpoint of a downstream API?
For example, if Service A needs to invoke an endpoint in Service B, we have two options:
a. Make the hostname and port number of Service B's API configurable in Service A (service-b:8080) and append the path URI in your code
or
b. Make the complete endpoint configurable in Service A (http://service-b:8080/somepath)
While I like the idea of making the endpoint configurable, it leaves a lot of room for error because the entire path needs to be specified. It also doesn't fit well when multiple endpoints need to be called from Service A to Service B which may potentially have different paths, requiring us to configure multiple endpoints.
On the other hand, option (a) seems more scalable due to above mentioned reasons.
Most search results online just demonstrated how a service can call another service and uses a hardcoded URL to demo this. It would be good to know how is the community doing this in real world projects.
P.S: We use Spring Webflux and deploy to k8s.

I have seen mostly that teams use option a, where the serviceB "baseUrl" (which is basically https://serviceb-hostname:8080) is injected as environment property (kubernetes configmap) into the application during deployment.
The specific API specific paths are configured in application yaml or in the "proxy config" class itself as constants (eg. ServiceBProxy.java - proxy classes are those which will make rest-calls to the dependent services like service B).
Here is a portion of application yaml from one of the microservices (from one of my projects):
authorizationService:
baseUri: ${authorizationServiceBaseUri}/api
tenantService:
baseUri: ${tenantServiceBaseUri}/api/v1
tenantsUri: ${tenantService.baseUri}/tenants
settingsService:
baseUri: ${settingsServiceBaseUri}
iamService:
fetchBatchSize: 500
baseUri: ${iamServiceBaseUri}
Here the values of iamServiceBaseUri,settingsServiceBaseUri,tenantServiceBaseUri,authorizationServiceBaseUri are all injected during deployment. And each of them contains the clusterIP with port.

Related

Mule API - deploy to a Mule Runtime

I am experimenting with Mule API management these days. What I come to know is we can deploy our API to one of these:
A Mule Runtime
An API Gateway
In the documentation, it is said that we should go with option 1 when we want to separate out the implementation of your API from the orchestration. What does it mean?
Can any one please explain in detail?
Policy management from API Platform and analytics generation can be achieved only by using a correctly configured API Gateway, which is a superset of Mule EE (current version is API Gateway 2.1.0 which contains Mule EE 3.7.2).
Depending on your architecture you may have different solutions.
For example:
Proxy running on API Gateway, implementation API running somewhere
else (eg. Mule EE/CE, Tomcat, cobol server, etc)
Proxy and implementation API running on the same API Gateway
Implementation API
managed directly from API Platform without using the autogenerated
proxies.
HTH :-)
Not exactly sure what they mean there, because on this page: https://developer.mulesoft.com/docs/display/current/API+Gateway they also mention this:
Note that the API Gateway, because it acts as an orchestration layer
for services and APIs implemented elsewhere, is technology-agnostic.
You can proxy non-Mule services or APIs of any kind, as long as they
expose HTTP/HTTPS, VM, Jetty, or APIkit Router endpoints. You can also
proxy APIs that you design and build with API Designer and APIkit to
the API Gateway to separate the orchestration from the implementation
of those APIs.
So both methods technically allow you to separate API from orchestration, as your API gateway application could simply proxy another Mule application elsewhere that performs the orchestration. But my understanding of the two options are:
The API gateway is a limited offering that allows you to use a subset of Mule's connectors, transports and modules such as ApiKit and HTTP, it allows you to expose and API then use http to connect to whatever backend systems you want as a proxy and perform the orchestration in the API layer.
By using the Mule runtime operation, it gives you much more flexibility and allows you to compose as many applications as you want using the full range of connectors etc. and separate out the different aspects of your applications into as many layers as you want as separately deployable entities that you can deploy to on-premise standalone instances or Cloudhub etc.
#Ryan answer is more or less on the mark, however if you do choose the Mule ESB offering you will loose out on the API Management and governance functionality that API gateway provides OOTB.
These include
Lets you enforce runtime policies and collect data for analytics
Applies policies to APIs or endpoints around security, throttling,
rate limiting, and more
Extends PingFederate to serve as identity management and OAuth
provider for your APIs
Lets you require or restrict certain behaviors in a few simple steps
Lets you add or remove policies at runtime with no API downtime
Manages access to your API by issuing contract keys
Monitors the API to confirm it is meeting all contract terms
Ensures compliance with service level agreements (SLAs)
In my opinion go with API Gateway/Manager if your API will be consumed my third party developers with whom you might not have too many interactions (think public API's) else Mule ESB should be good.
You should be able to migrate from Mule ESB to API Manager (and vice versa) also easily if you need to, so I do not think you will get locked into your decision
PS: Content copied from here

WCF Service hosted in Worker Role on Windows Azure that acts like a proxy and needs to call other services hosted in other Worker Roles

as you can see, I am relatively new on SO please don't kill me after posting this question :) I will do my best to describe the dilemma I am currently in.
I am creating something like a "Guardian Service" that is hosted on Windows Azure inside a Worker Role. This service has external ports, that can be accessed via HTTPS to allow clients to call it's service methods.
The WCF service is meant to call other services hosted in other Worker Roles that have only internal ports open, and which can be accessed only through the use of the Guardian Service. That's the main idea. Similar to a proxy or something.
I read already an excellent article from Jim O'Neil, what the caveats are when you try to access internal service points from within other WCF Services hosted in worker Roles:
His blog Troubleshooting Endpoints on a WCF Web Role
This is not the point for this question, and totally clear to me how to do that.
I have no idea at the moment, how I could do this, without implementing every contract from every single service I want to make accessible from within the Guardian Service to the outside world.
There must be a better way to decouple those things.
Any tips are appreciated.
Thank you.
I do not know the exact requirements for your project but I would say that what you are looking for is WCF Routing. I've used it in the past to redirect requests for different versions of Workflow instances.
The way it works is completely transparent to the client connecting to its endpoint. The router implementation must decide where to send the requests to, based on the request data (message headers and body).
In your case, if you are using SOAP and namespaces correctly, you might be able to base your decision on the message soap address and then send the request to the correct endpoint. You could also look at the Action property of the message.
Some links that might be useful:
http://msdn.microsoft.com/en-us/library/ee517423.aspx
http://www.codeproject.com/Articles/227699/RoutingService-on-Azure

Azure endpoints - different deployments

Currently we run a UI web role and a web service web role(WCF REST) on Azure. Each role contains 2 instances (for load balancing and meeting the SLA reqs.)
The UI Web role and web service web role are within the same subscription but in different deployments. We do not want to merge the code bases (maintainability etc etc). So the UI layer is on xyz.cloudapp.net and the Web Service layer is on abc.cloudapp.net.
Currently, the requirement is to make the web service web role an internal endpoint i.e only accessible by the UI layer. The literature on configuring internal endpoints and accessing it from a different deployment is not very clear.
I am assuming that the two different roles need to be part of a single deployment for this to work. Can this be done without affecting the deployments? Any pointers in the right direction would be greatly appreciated.
Internal endpoints are only accessible within a single deployment, and do not route through the load balancer (so if you have 2 instances of your wcf services accessible on internal endpoint, you'd need to distribute calls between the instances). This, of course, would require you to put both your web role and wcf web role into the same deployment.
You might want to consider service bus for a secure way of reaching your wcf services from your web role instances. Or... expose the wcf services via input endpoint but secure the service.
There's an approach I like to call the virtual DMZ that sould meet your needs: http://brentdacodemonkey.wordpress.com/?s=virtual+dmz
It leverages the ACS and WCF bindings to allow you to create access control to input endpoints (which are then load balanced). Of course, if you don't want something tha robust, you can go with just a standard old WCF mutual auth scenario.
That said, David makes an excellent point. Internal endpoints are only accessible with a single deployed service. This is because that service represents an isolation boundary (think virtual lan branch) and the only input endpoints can be adressed from outside of that boundary.
Have you considered using ACS (Access Control Services) for restricting access using claims-based authentication to your WCF endpoint?
There are numerous protection schemes you could provide via WCF bindings.
Internal Endpoints can only communicate with inter-roles in the same deployment. If you have 2 separate deployments (abc.cloudapp.net and xyz.cloudapp.net, internal endpoints won't help you).

Multiple service with Single endpoint in Client side (Consuming Application)

I am having multiple WCF service but while consuming the service in Web application each service having its own end point to access the service. I need to have single end point in my web application to access all the services. Is there any other way except partial class.
No this can't be done. You can't merge multiple services into one endpoint.
You mention a partial class definition. That actually means you merge your different services together and expose them as one single service. This can off course be done and would give you one single access point (since it's just one service).
This way you could still logically separate the code in different files and let the them each implement a single interface. The service as a whole would implement a combined interface of all the different elements and that's what you would expose as a service endpoint.
--EDIT--
I personally wouldn't merge the services into one big service because that one big service will have to process all the incoming request. What if you want a certain configuration setting for one service, or you want to do some load balancing and move several services to another server?
If the problem is in maintaning the web.config files, you should have a look at web.config transformations. That way you can automate the process of configuring your application for different deployment scenarios.

WCF: Client config for non-.net-clients

I am developing a wcf service (basicHttpBinding) that should also be consumed by non .net clients (e.g. Java clients). But now I wonder how the client can define his client config file. Or is this file only needed for .net-clients? (I am thinking of configurations like maxReceivedMessageSize or maxItemsInObjectGraph for example).
Each development platform (call it as you want: SOAP stack, Framework, API) has its own way to configure communication. You don't need to bother with it. You just need to expose correct WSDL and client's developer will be responsible for configuring the client application based on his needs.
If you want to extend documentation of your service in WSDL you can use wsdl:documentation. WCF doesn't offer it by default but you can use this technology sample to extend WCF. You can use such documentation for example to describe that service operation can return large amount of data. Another approach to add wsdl:documentation is using WCF Extras.
From the sound of it, the client shouldn't have access to those configuration options. For instance, why should a client to the WCF service be able to specify the maxReceivedMessageSize?
What you probably want to do is define these configuration options on the server-side. If a client makes a call and there is a conflict with one of your options (i.e. the client exceeds maxReceivedMessageSize), you'll want to throw a SoapException back to the client.
If you want to let the client have access to the configuration settings before he or she sends a request, you can always implement a simple web service method that sends back the values.