James
James

Reputation: 3184

How can a client call Spring Data Rest endpoints?

I have Spring Boot web application with a UI built using HTML / CSS / JavaScript. I have another Spring Boot application that exposes Spring Data Rest endpoints. Both applications are registered with an Eureka service registry.

I want the UI application to call one of the rest endpoints of the other application. It will use the data to populate a drop down box on an HTML page. To do this, I'm trying to have the JavaScript directly call the REST API via Traverson:

traverson.registerMediaType(TraversonJsonHalAdapter.mediaType, 
         TraversonJsonHalAdapter);

traverson
        .from("http://spring-data-rest-server:8081/api/cars")
        .jsonHal()
        .newRequest()
        .follow(list)
        .getResource(...

There are two problems with this approach:

  1. The UI gets a 403 stating strict-origin-when-cross-origin
  2. The URL is hardcoded rather than looked up from the service registry.

How can I have Traverson call the Spring Data Rest cars endpoint without hardcoding the URL and avoiding the 403?

Upvotes: 0

Views: 518

Answers (1)

yejianfengblue
yejianfengblue

Reputation: 2429

1. CORS 403 issue

According to spring data rest doc, you can either configure CORS on repository interface

@CrossOrigin(origins = "http://domain2.example",
  methods = { RequestMethod.GET, RequestMethod.POST, RequestMethod.DELETE },
  maxAge = 3600)
interface PersonRepository extends CrudRepository<Person, Long> {}

or repository rest controller

@RepositoryRestController
public class PersonController {

  @CrossOrigin(maxAge = 3600)
  @RequestMapping(path = "/people/xml/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_XML_VALUE)
  public Person retrieve(@PathVariable Long id) {
    // …
  }
}

or global

@Component
public class SpringDataRestCustomization implements RepositoryRestConfigurer {

  @Override
  public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config, CorsRegistry cors) {

    cors.addMapping("/person/**")
      .allowedOrigins("http://domain2.example")
      .allowedMethods("PUT", "DELETE")
      .allowedHeaders("header1", "header2", "header3")
      .exposedHeaders("header1", "header2")
      .allowCredentials(false).maxAge(3600);
  }
}

2. Hardcoded URL issue

2.1. get the host and port from service registry. The path fragment /api may be hardcoded or set in the service registry side because it's a convention set by you.

2.2. Traverson calls http://host:port/api, then you should have a response body

{ 
  "_links" : {
    "cars" : {
      "href" : "http://spring-data-rest-server:8081/api/cars"
    }
  }
}

get href from the cars link

Upvotes: 1

Related Questions