自訂 Spring Data REST

Spring Data REST 提供了許多自訂選項。以下小節將說明如何操作。

自訂項目資源 URI

預設情況下,項目資源的 URI 由用於集合資源的路徑區段以及附加的資料庫識別碼組成。這樣您就可以使用 repository 的 findOne(…) 方法來查詢實體實例。從 Spring Data REST 2.5 開始,可以使用 RepositoryRestConfiguration 上的組態 API(Java 8 上較佳)或在您的應用程式中註冊 EntityLookup 的實作作為 Spring Bean 來進行自訂。Spring Data REST 會選取這些並根據其實作調整 URI 的產生方式。

假設一個 User 具有唯一識別它的 username 屬性。進一步假設我們在對應的 repository 上有一個 Optional<User> findByUsername(String username) 方法。

在 Java 8 上,我們可以將對應方法註冊為方法參考,以調整 URI 建立,如下所示

@Component
public class SpringDataRestCustomization implements RepositoryRestConfigurer {

  @Override
  public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
    config.withEntityLookup()
      .forRepository(UserRepository.class)
      .withIdMapping(User::getUsername)
      .withLookup(UserRepository::findByUsername);
  }
}

forRepository(…) 將 repository 類型作為第一個引數,將 repository 網域類型對應到某個目標類型的方法參考作為第二個引數,以及另一個方法參考,使用第一個引數中提及的 repository 將該值對應回去。

如果您沒有執行 Java 8 或更高版本,您可以使用該方法,但它需要一些相當冗長的匿名內部類別。在較舊的 Java 版本上,您可能應該優先實作一個類似於以下的 UserEntityLookup

@Component
public class UserEntityLookup extends EntityLookupSupport<User> {

    private final UserRepository repository;

    public UserEntityLookup(UserRepository repository) {
        this.repository = repository;
    }

    @Override
    public Serializable getResourceIdentifier(User entity) {
        return entity.getUsername();
    }

    @Override
    public Object lookupEntity(Serializable id) {
        return repository.findByUsername(id.toString());
    }
}

請注意 getResourceIdentifier(…) 如何傳回要由 URI 建立使用的使用者名稱。為了透過該方法傳回的值載入實體實例,我們現在使用 UserRepository 上可用的查詢方法來實作 lookupEntity(…)

自訂 repository 公開

預設情況下,所有公開的 Spring Data repository 都會用於公開 HTTP 資源,如Repository 資源中所述。套件保護的 repository 介面會從此清單中排除,因為您表示其功能僅在套件內部可見。這可以透過在 RepositoryRestConfiguration 上明確設定 RepositoryDetectionStrategy(通常透過 enum RepositoryDetectionStrategies)來自訂。可以設定以下值

  • ALL — 公開所有 Spring Data repository,無論其 Java 可見性或註解組態為何。

  • DEFAULT — 公開公開的 Spring Data repository 或明確使用 @RepositoryRestResource 註解且其 exported 屬性未設定為 false 的 repository。

  • VISIBILITY — 僅公開公開的 Spring Data repository,無論註解組態為何。

  • ANNOTATED — 僅公開明確使用 @RepositoryRestResource 註解且其 exported 屬性未設定為 false 的 Spring Data repository。

如果您需要套用自訂規則,只需手動實作 RepositoryDetectionStrategy 即可。

自訂支援的 HTTP 方法

自訂預設公開

預設情況下,Spring Data REST 會根據 repository 公開的 CRUD 方法,如Repository 資源中所述,公開 HTTP 資源和方法。repository 不需要擴充 CrudRepository,但也可以選擇性地宣告上述章節中描述的方法,並且資源公開將會遵循。例如,如果 repository 未公開 delete(…) 方法,則項目資源將不支援 HTTP DELETE

如果您需要宣告一個供內部使用的方法,但不希望它觸發 HTTP 方法公開,則可以使用 @RestResource(exported = false) 註解 repository 方法。要在哪些方法上使用此註解來移除對哪些 HTTP 方法的支援,請參閱Repository 資源

有時,在方法層級管理公開不夠精細。例如,save(…) 方法用於支援集合資源上的 POST,以及項目資源上的 PUTPATCH。若要選擇性地定義應公開哪些 HTTP 方法,您可以使用 RepositoryRestConfiguration.getExposureConfiguration()

此類別公開基於 Lambda 的 API,以定義全域和基於類型的規則

ExposureConfiguration config = repositoryRestConfiguration.getExposureConfiguration();

config.forDomainType(User.class).disablePutForCreation(); (1)
config.withItemExposure((metadata, httpMethods) -> httpMethods.disable(HttpMethod.PATCH)); (2)
1 停用對 HTTP PUT 的支援,以直接建立項目資源。
2 停用對所有項目資源上的 HTTP PATCH 的支援。