2

I am trying to create microservices using Spring-boot Java and SteelToe ASP.NET

Step-1: I created a full service using Java (A service with UI and API. It is hosted on PCF). The API has ClassesControler defined inside.

Step-2: Create a microservice using ASP.NET, SteelToe. Register the service in Eureka and make it discoverable using Zuul.

Step-3: Use the Interface, Service approach to access the JAVA microservice(s)

namespace employee-client.Service
{
    public interface IRelayService
    {
        Task<HttpResponseMessage> getClassesList(string relativeUrl = "/api/v1/classes");
    }
}

Service with Implementation for Interface:

namespace employee-client.Service
{
    public class RelayService : IRelayService
    {
        DiscoveryHttpClientHandler _handler;
        string _accessToken;

        private const string BASE_URL = "https://www.example.com";

        public QortaService(IDiscoveryClient client, string accessToken)
        {
            _handler = new DiscoveryHttpClientHandler(client);
            _accessToken = accessToken;
        }

        public async Task<HttpResponseMessage> getClassesList(string relativeUrl)
        {
            string classesUrl= BASE_URL + relativeUrl;

            HttpClient client = GetClient();
            HttpRequestMessage request = new HttpRequestMessage();
            request.RequestUri = new Uri(classesUrl);
            request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _accessToken);

            return await client.SendAsync(request, HttpCompletionOption.ResponseContentRead);
        }

        private HttpClient GetClient()
        {
            var client = new HttpClient(_handler, false);
            return client;
        }
    }
}

I came up with this approach based on the example in SteelToe but I hate hardcoding the BASE_URL. Question: I very much like the @FeignClient annotation approach used in Java. Any ideas about how I can access an existing microservice in a better way. If so, an example would be much appreciated

Edit: I modified the question to make more clear. The flow of traffic is from Java Service to .NET service. .NET service requests for a list of classes from the controller in JAVA service (ClassesController.java)

Jop.pop
  • 335
  • 4
  • 18

2 Answers2

1

I'm unclear which direction traffic is flowing in your scenario, but I think you're saying the .NET application is trying to call the Java application. The code you're using is from before HttpClientFactory was introduced and is a bit clunkier than what's possible now in general. Steeltoe can be used with HttpClientFactory for a better overall experience.

Steeltoe has debug logging available to confirm the results of service lookup if you set logging:loglevel:Steeltoe.Common.Discovery = true in your application config.

You didn't mention specifically what isn't working, but I'm guessing you're getting a 404 since it looks like your code will create a request path looking like https://fortuneService/api/fortunes/random/api/v1/classes

If you're looking for something like Feign in .NET, you could try out DHaven.Faux

Tim
  • 2,587
  • 13
  • 18
  • I edited my question. Hope it gives a better understanding of what I intend to do. Unfortuantely, DHaven.Faux doesn't look very active and doesn't meet our org standards – Jop.pop May 22 '20 at 18:26
  • SteelToe HttpClientFactory has the answers. Thanks – Jop.pop May 25 '20 at 22:37
0

For others who are looking for the same:

namespace employee-client.Service
{
    public class RelayService : IRelayService
    {
        private const string CLASSES_API_SERVICEID = "classes-api";
        IDiscoveryClient _discoveryClient;
        DiscoveryHttpClientHandler _handler;
        string _accessToken;

        public RelayService(IDiscoveryClient discoveryClient, string accessToken)
        {
            _discoveryClient = discoveryClient;
            _handler = new DiscoveryHttpClientHandler(client);
            _accessToken = accessToken;
        }

        public async Task<HttpResponseMessage> getClassesList()
        {
             var classesApiInstances = _discoveryClient.GetInstances(CLASSES_API_SERVICEID);
             Uri classesApiUri = classesApiInstances[0].Uri;
             string classesUrl= classesApiUri.AbsoluteUri + relativeUrl;

             HttpClient httpClient = GetClient();
             HttpRequestMessage request = new HttpRequestMessage();
             request.RequestUri = new Uri(classesUrl);
             request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _accessToken);

             return await httpClient.SendAsync(request, HttpCompletionOption.ResponseContentRead);
        }

        private HttpClient GetClient()
        {
            var client = new HttpClient(_handler, false);
            return client;
        }
    }
}
Jop.pop
  • 335
  • 4
  • 18