Supun Sameera
Supun Sameera

Reputation: 2703

Spring Boot RepositoryRestResource with FeignClient

I have built two spring-boot apps, server side spring-boot micro-service with rest resources and client side spring-boot micro-service app consuming HATEOAS feed using Feign Clients.

I have two entity objects Aggregate and Gateway, on both sides. Gateway is inside Aggregate object

As long as i don't have @RepositoryRestResource interface for Gateway object i can retrieve Gateway object through Aggregate, but if I have the annotation i can't get the Gateway listed on Aggregate object on client side. I have noticed this is because server side HATEOAS feed adds link for Gateway on Aggregate instead of Json structure for Gateway.

Is there anyway i can still get Gateway object from Aggregate object while having a @RepositoryRestResource interface for Gateway object? Or is there a way to configure Feign Client to fill the Gateway object from the link?

Ex.. From Client http://localhost:9999/aggregates/

With @RepositoryRestResource annotation on GatewayRepository

[
  {
    "id": "a65b4bf7-6ba5-4086-8ca2-783b04322161",
    "gateway": null, //<-- Gateway is null here
    .......

Without @RepositoryRestResource annotation on GatewayRepository

[
  {
    "id": "a65b4bf7-6ba5-4086-8ca2-783b04322161",
    "gateway": { //<-- Gateway id and properties are there now on Aggregate object
      "id": "4a857a7a-2815-454c-a271-65bf56dc6f79",
    .......

From Server http://localhost:8000/aggregates/

With @RepositoryRestResource annotation on GatewayRepository

{
  "_embedded": {
    "aggregates": [
      {
        "id": "a65b4bf7-6ba5-4086-8ca2-783b04322161",
        "_links": {
          "self": {
            "href": "http://localhost:8000/aggregates/a65b4bf7-6ba5-4086-8ca2-783b04322161"
          },
          "gateway": { //<-- Gateway becomes a link here
            "href": "http://localhost:8000/aggregates/a65b4bf7-6ba5-4086-8ca2-783b04322161/gateway"
          },
        .......

Without @RepositoryRestResource annotation on GatewayRepository

  "_embedded": {
    "aggregates": [
      {
        "id": "b5171138-4313-437a-86f5-f70b2b5fcd22",
        "gateway": { //<-- Gateway id and properties are there now on Aggregate object
          "id": "3608726b-b1b1-4bd4-b861-ee2bf5c0cc03",
        .......

Here are my server side implementation of model objects

@Entity
class Aggregate extends TemplateObject {
    @OneToOne(cascade = CascadeType.MERGE)
    private Gateway gateway;
    .......
}

@Entity
class Gateway extends TemplateObject {
    @NotNull
    @Column(unique = true)
    private String name;
    .......
}

And Server side rest repositories are

@RepositoryRestResource
interface GatewayRepository extends JpaRepository<Gateway, String> {
    Optional<Gateway> findByName(@Param("name") String name);
}

@RepositoryRestResource
interface AggregateRepository extends JpaRepository<Aggregate, String> {
    Optional<Aggregate> findByName(@Param("name") String name);
}

(Using these Rest Resources on port 8000)

On client side i have the same implantation on model dto objects

class Gateway extends TemplateObject {
    @NotNull
    private String name;
    .......
}

class Aggregate extends TemplateObject {
    private Gateway gateway;
    .......
}

And Feign clients

@FeignClient("billing-service/gateways")
interface GatewayService extends GenericService<Gateway> {
}

@FeignClient("billing-service/aggregates")
interface AggregateService extends GenericService<Aggregate> {
}

(Using these Feign clients on port 9999 client controllers)

Thanks in advance for help, any advice and suggestions is greatly appreciated

Upvotes: 1

Views: 1669

Answers (1)

dcpastoors
dcpastoors

Reputation: 107

You may have a look at using projections along with your rest repositories - have a look here. Afterwards you have only to adapt your FeignClient request paths to provide the respective projection as a parameter.

Upvotes: 1

Related Questions