24 Aralık 2020 Perşembe

SpringCloud Feign @FeignClient Anotasyonu

Giriş
Şu satırı dahil ederiz
import org.springframework.cloud.netflix.feign.FeignClient;
configuration Alanı
Örnek - Basic Authentication
Şöyle yaparız
import feign.auth.BasicAuthRequestInterceptor;

public class ZephyrFeignClientConfiguration {

  @Value("${zephyr.api.username}")
  private String jiraApiUsername;

  @Value("${zephyr.api.password}")
  private String jiraApiPassword;

  @Bean
  public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
    return new BasicAuthRequestInterceptor(jiraApiUsername, jiraApiPassword);
  }
}

@FeignClient(name = "...", url = "...", 
  configuration = ZephyrFeignClientConfiguration.class)
public interface ZephyrFeignClient {

  @RequestMapping(value = "/execution", method = RequestMethod.GET)
  ExecutionListResponseDto getListOfExecutions(@RequestParam(name = "issueId") 
    String issueId);

}
Açıklaması şöyle
Notice — do not mark the whole class as @Configuration. This would make the BasicAuthRequestInterceptor bean available in the whole Spring context and therefore it would be picked up by other Feign Clients.
Örnek - Token Authentication
Şöyle yaparız
import feign.RequestInterceptor;
import feign.RequestTemplate;

public class SlackFeignClientConfiguration {

  @Value("${slack.app.oauth.accessToken}")
  private String slackOauthAccessToken;

  @Bean
  public RequestInterceptor bearerTokenRequestInterceptor() {
    return new RequestInterceptor() {
      @Override
      public void apply(RequestTemplate template) {
        template.header("Authorization",
                        String.format("Bearer %s", slackOauthAccessToken));
      }
    };
  }
}

@FeignClient(name = "Slack", url = "...", 
  configuration = SlackFeignClientConfiguration.class)
public interface SlackFeignClient {

  @RequestMapping(
    value = "/chat.postMessage",
    method = RequestMethod.POST,
    consumes = "application/json",
    produces = "application/json")
  SlackMessageResponseDto postSlackMessage(@RequestBody(required = true) 
    SlackMessageRequestDto messageRequest);
}
fallback Alanı
Bu alanın çalışması için application.properties dosyasına şu eklenir. Böylece servis çalışmıyorsa fallback metodu çağrılır
feign.circuitbreaker.enabled=true
Örnek
Şöyle yaparız
@FeignClient(name="score-segment", fallback = ScoreSegmentFallback.class)
public interface ScoreSegmentProxy {

    @GetMapping("/score-segment/{idNumber}")
    public ScoreSegmentResponse retrieveExchangeValue(@PathVariable BigInteger idNumber);
}

@Component
public class ScoreSegmentFallback implements ScoreSegmentProxy {

  @Override
  public ScoreSegmentResponse retrieveExchangeValue(BigInteger idNumber) {
    return new ScoreSegmentResponse(BigInteger.ONE);
  }
}
name Alanı
url belirtilmediği için Eureka sunucusundan servisi bulur

Örnek
Şöyle yaparız
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import com.example.EmployeeDashBoardService.domain.model.EmployeeInfo;

@FeignClient(name="EmployeeSearch" )//Service Id of EmployeeSerach service
public interface EmployeeServiceProxy {

   @RequestMapping("/employee/find/{id}")
   public EmployeeInfo findById(@PathVariable(value="id") Long id);

   @RequestMapping("/employee/findall")
   public Collection<EmployeeInfo> findAll();

}
Açıklaması şöyle
Feign dynamically generates the implementation of the interface we created, so Feign has to know which service to call beforehand. That's why we need to give a name for the interface, which is the {Service-Id} of EmployeeService. Now, Feign contacts the Eureka server with this Service Id, resolves the actual IP/hostname of the EmployeeService, and calls the URL provided in Request Mapping.
url Alanı
Eğer Eureka kullanmıyorsak, URL ile adresi belirtmek gerekir.

Örnek - application.properties
application.properties şöyle olsun
zephyr:
  api:
    baseUrl: https://jira.my-company.com/jira/rest/zapi/latest
Şöyle yaparız
@FeignClient(name = "Zephyr", url = "${zephyr.api.baseUrl}", 
  configuration = ZephyrFeignClientConfiguration.class)
public interface ZephyrFeignClient {

  @RequestMapping(value = "/execution", method = RequestMethod.GET)
  ExecutionListResponseDto getListOfExecutions(@RequestParam(name = "issueId") 
    String issueId);

}

Örnek - dynamic URL
Şöyle yaparız
import java.net.URI;

@FeignClient(name = "exchangeratelistfeignservice",url = "https://dummy.com")
public interface ExchangeRateListFeignService {
  @GetMapping("")
  ResponseEntity<String> getAllExchangeRates(URI baseUrl);
}

@GetMapping Örnekleri
Örnek
Şöyle yaparız
@FeignClient(name = "jsonplaceholder", url = "https://...")
public interface PostClient {
  @GetMapping
  List<PostDTO> getPosts();
}
Örnek
Şöyle yaparız
@FeignClient(url = "<host:port for serviceB>", name = "serviceB")
public interface ServiceBClient{
  @GetMapping("/hello")
  public ResponseEntity<String> sayHello();
}
Örnek - @PathVariable İle Parametre
Şöyle yaparız
@FeignClient(name = "products", url = "https://dummyjson.com/products")
public interface ProductClient {

  @GetMapping("/{id}")
  Product fetchProduct(@PathVariable int id);
}
@RequestMapping Örnekleri

Örnek - @RequestMapping ile Get
Şöyle yaparız
@FeignClient(name = “external-service”, url = “${external-service.url}”,
configuration = ServiceConfiguration.class) 
public interface ExternalServiceClient
 
  @RequestMapping(method = RequestMethod.GET, value = “/external- data/{time}”,
consumes = “application/json”
  Data load(@PathVariable(“time”) Long time); 
}
Örnek
Şöyle yaparız
@FeignClient(name = "bonus", url = "http://localhost:8081/bonus")
public interface BonusClient {

  @RequestMapping(value = "/register", method = RequestMethod.POST)
  String register();
}

@FeignClient(name = "notification", url = "http://localhost:8082/notification")
public interface NotificationClient {

  @PostMapping("/send")
  String send(@RequestBody NotificationRequest notificationRequest);
}

@RestController
@RequestMapping("/bonus")
public class BonusController {

  @PostMapping("/register")
  String register() {
    ...
  }
}

@RestController
@RequestMapping("/notification")
public class NotificationController {

   @PostMapping("/send")
   String send(@RequestBody NotificationRequest notificationRequest) {
     ...
  }
}
Örnek - RequestMapping + BasicAuthRequestInterceptor
BasicAuthentication kullanarak Get isteği göndermek için şöyle yaparız. Burada Spring MVC'ye aiıt
@DeleteMapping
@GetMapping
@PostMapping
@PutMapping
kullanılabilir.

Parametre geçmek için 
@PathVariable
@RequestHeader
@RequestParam
kullanılabilir.
import org.springframework.cloud.openfeign.FeignClient;

@FeignClient(name = "Zephyr", url = "${zephyr.api.baseUrl}",
configuration = ZephyrFeignClientConfiguration.class)
public interface ZephyrFeignClient {

  @RequestMapping(value = "/execution",method = RequestMethod.GET)
  Foo getListOfExecutions(@RequestParam(name = "issueId") String issueId);

}
Burada url değeri application.yml dosyasında şöyle tanımlı
zephyr:
api: baseUrl: https://jira.my-company.com/jira/rest/zapi/latest
Şöyle yaparız
import feign.auth.BasicAuthRequestInterceptor;

public class ZephyrFeignClientConfiguration {

  @Value("${zephyr.api.username}")
  private String jiraApiUsername;

  @Value("${zephyr.api.password}")
  private String jiraApiPassword;

  @Bean
  public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
    return new BasicAuthRequestInterceptor(jiraApiUsername, jiraApiPassword);
  }

}
Kullanmak için şöyle yaparız
@Service
@RequiredArgsConstructor
public class MyService {

  private final ZephyrFeignClient zephyrClient;

  public void fetchData() {
    Foo foo = zephyrClient.getListOfExecutions("5112096");
    ...
  }
}

Hiç yorum yok:

Yorum Gönder