1

Spring Data Rest従来のリレーショナル DB を介して提供される RESTful サービスを操作する Web フロント エンドの実装を開始しました。これは で行われ、私が見つけAngularJSたライブラリは の哲学と形式主義にangular-hal非常によく適合しています。HATEOASSpring Data Rest

たとえば、最初の API エンドポイント (「/」) を知る必要があるだけで、すべてのクエリは URL を気にせずにリレーションを介して実行されます。私が抱えている問題は、エンティティの 1 つを表示しているページに直接アクセスできることです。

連絡先リポジトリの例を見てみましょう。ホームページから開始し、連絡先リストをナビゲートして、詳細を確認したい連絡先を選択すると、問題はありません。

しかし、連絡先の詳細を表示するページに直接アクセスすることはできません。リソースはリスト コントローラーから編集コントローラーに注入され、編集コントローラーは、リスト コントローラーから指示されない場合、要求する URL を知ることができません。

根本的な問題はSpring Data Rest、エンティティには (JSON ではなく) エンティティのパブリック フィールドがなく、リポジトリにはID で検索するidAPI がないことです。relation

いくつかの解決策を考えましたが、どれも気に入りません。

1. バックエンドで回避する

  • ブックマークする必要があるすべてのエンティティにProjectionwith メソッドを追加しますgetId()
  • findById()対応するものをリポジトリ インターフェイスに 追加します
  • フロントエンドの URL の ID をパラメーター (またはパス) として使用し、新しく利用可能な検索関係を呼び出してリソースを解決します。
  • 欠点: これにより、Spring Data Rest によって自動的に生成されたすべての DTO を手動でやり直す必要があるため、フレームワークの目的の 1 つが失われています。
  • 質問: これらの id フィールドと findById メソッドを自動的に公開するように Spring を構成する方法はありますか?

2.自己関係を利用する

  • angular-hal $href('self')メソッドでエンティティのセルフ URI を取得する
  • halClient.$get(resourceUri)それをページのパラメーターとして使用し、その上でnew を呼び出してリソースを解決します
  • 欠点: アドレス バーの別の "http://" によるエラーを防ぐために、ページの URL を挿入する前後に URI を処理する必要があります。それにbase64エンコーディングを行うことを考えましたが、これは消費しています。
  • 欠点: これにより、API の URL が公開されます。このデータは重要であり、非表示にする必要があります (ネットワーク トラフィックを監視しているデバッガーを介してアクセスできる場合でも)。

3.HATEOASを忘れる

  • 関係と検出機能を気にしないでください
  • 単純な古い URL マッピングを削除しangular-halて使用する$resource
  • 欠点:これは逆行しており、ガイドラインに従っていないように感じます...

それで、何か不足していますか?完全な RESTFul HATEOAS 環境でのデータ アクセスに関するベスト プラクティスは何ですか?

4

1 に答える 1

1

exposeIdsForJSON に @Id アノテーションが付けられたフィールドを追加できるメソッドを見つけました。

@Configuration
public class RepositoryConfiguration  extends SpringBootRepositoryRestMvcConfiguration {

    /**
     * add here the main resources that would need direct access from outside
     */
    @Override
    protected void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
        config.exposeIdsFor(Contact.class, User.class);
    }
}

次に、IDを公開して共通の抽象クラスから継承するすべてのエンティティを作成しました

@MappedSuperclass
public abstract class AbstractEntity {

    @Id @GeneratedValue
    Long id;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
}

この抽象クラスは@NoRepositoryBeanリポジトリによって提供されます

@NoRepositoryBean
public interface AbstractEntityRepository<T extends AbstractEntity> extends JpaRepository<T, Long> {    
    @RestResource(rel = "byId")
    T findById(@Param("id") Long id);
}

次に、気になるエンティティの id とメソッド byId() の両方を公開できます。

@Entity
public class Contact extends AbstractEntity {

    @Column 
   String name;

    @Column 
    String email;
}

public interface ContactRepository extends AbstractEntityRepository<Contact> {    
}

これは良い回避策であり、クライアントからのエンティティへの直接アクセスを少額で可能にすると思います

于 2015-07-31T08:13:32.400 に答える