定製 Spring Data REST

Spring Data REST 有許多定製選項。以下小節展示瞭如何進行定製。

定製 Item Resource URI

預設情況下,Item Resources 的 URI 由 Collection Resource 使用的路徑段附加資料庫識別符號構成。這允許您使用儲存庫的 findOne(…) 方法查詢實體例項。從 Spring Data REST 2.5 版本開始,您可以透過 RepositoryRestConfiguration 上的配置 API(推薦在 Java 8 上使用)或註冊 EntityLookup 的實現作為 Spring Bean 來定製這一點。Spring Data REST 會拾取這些實現並根據其實現調整 URI 生成。

假設有一個 User 實體,其 username 屬性唯一標識它。進一步假設相應的儲存庫上有一個 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(…) 方法接受儲存庫型別作為第一個引數,一個將儲存庫的領域型別對映到目標型別的方法引用作為第二個引數,以及另一個使用第一個引數提到的儲存庫將該值映射回的方法引用。

如果您沒有執行 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(…)

定製儲存庫暴露

預設情況下,所有公共 Spring Data 儲存庫都用於暴露 HTTP 資源,如儲存庫資源中所述。Package Protected 儲存庫介面被排除在此列表之外,因為您表示其功能僅在包內部可見。這可以透過在 RepositoryRestConfiguration 上顯式設定 RepositoryDetectionStrategy(通常透過列舉 RepositoryDetectionStrategies)來定製。可以配置以下值:

  • ALL — 暴露所有 Spring Data 儲存庫,無論其 Java 可見性或註解配置如何。

  • DEFAULT — 暴露公共 Spring Data 儲存庫或那些顯式使用 @RepositoryRestResource 註解且其 exported 屬性未設定為 false 的儲存庫。

  • VISIBILITY — 僅暴露公共 Spring Data 儲存庫,無論註解配置如何。

  • ANNOTATED — 僅暴露顯式使用 @RepositoryRestResource 註解且其 exported 屬性未設定為 false 的 Spring Data 儲存庫。

如果您需要應用自定義規則,只需手動實現 RepositoryDetectionStrategy 即可。

定製支援的 HTTP 方法

定製預設暴露

預設情況下,Spring Data REST 根據儲存庫暴露的 CRUD 方法,暴露 HTTP 資源和方法,如儲存庫資源中所述。儲存庫不需要擴充套件 CrudRepository,也可以選擇性地宣告前述部分中描述的方法,資源暴露將隨之改變。例如,如果儲存庫未暴露 delete(…) 方法,則 Item Resource 將不支援 HTTP DELETE

如果您需要宣告一個用於內部使用的方法,但不想讓它觸發 HTTP 方法暴露,則可以透過 @RestResource(exported = false) 註解該儲存庫方法。關於哪些方法應該如何註解以移除對哪些 HTTP 方法的支援,請參閱儲存庫資源

有時,在方法級別管理暴露不夠細粒度。例如,save(…) 方法用於支援 Collection Resource 上的 POST,以及 Item Resource 上的 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 停用直接建立 Item Resource 的 HTTP PUT 支援。
2 停用所有 Item Resource 的 HTTP PATCH 支援。