2017-05-08 107 views
0

我已經經歷了幾個教程,我可以看到JAX-RS註釋創建的接口。稍後將完成相同的實現。爲什麼要爲JAX-RS實現聲明一個接口?

這是爲什麼?我無法直接將具體類作爲REST風格的服務公開嗎?這是一種不好的做法嗎?以下是我在this問題中遇到的其中一個示例。

public interface ICRUD { 

    @POST 
    @Consumes("application/json") 
    @Produces("application/json") 
    @Path("create") 
    public String createREST(String transferObject); 

    @GET 
    @Consumes("application/json") 
    @Produces("application/json") 
    @Path("retreive/{id}") 
    public String retreiveREST(@PathParam("id") String id); 

    @POST 
    @Consumes("application/json") 
    @Produces("application/json") 
    @Path("update") 
    public void updateREST(@Suspended final AsyncResponse asyncResponse, 
          final String transferObject) ; 

    @DELETE 
    @Consumes("application/json") 
    @Produces("application/json") 
    @Path("delete/{id}") 
    public String deleteREST(@PathParam("id") String id); 
} 

回答

1

簡而言之 - 接口不是強制性的。你可以將一個類作爲一個服務公開。

這裏有一個關於這個的大討論 https://softwareengineering.stackexchange.com/questions/150045/what-is-the-point-of-having-every-service-class-have-an-interface

+0

我確實看過帖子,但無法理解Donal Fellows的回答。你可以把它放在一些燈光?它說像Spring這樣的框架的交叉會更簡單。怎麼樣? – Sam

+2

從我使用OSGI的期限來看,我會說,當服務實現從其他機器/環境/類加載器加載並執行時,存在一種常見的情況。服務和實現的分離使我能夠導入API接口,並且「不關心」其他團隊編寫的實現。在實現代碼中進行的更改不會影響我的代碼,所以這是減少耦合的方式 – Kirill

2

我不能直接公開的具體類作爲RESTful服務?

你一定可以。你試過了嗎?它應該工作得很好。

這是不好的做法?

個人(這只是我的偏好),我認爲使用接口是不好的做法。有些人可能會爭辯說它會清理你的代碼,但是使用接口會帶來一些問題,比如annotation inheritance有時會給那些不明白問題出在哪裏的人帶來問題。它可能很難被發現。

如果你的觀點是接口使代碼更清晰,我有幾個參數。

(1)您的代碼不太可以理解。您需要繼續回頭查看接口以查看哪些參數適用於(例如檢查方法參數註釋)。所有註釋都在您實際編寫的代碼中時更容易。

(2)接口沒有實現,所以你仍然需要實現每個類。我個人會選擇一個抽象基類來實現所有基本操作。例如

public abstract class AbstractResource<T extends BaseEntity> { 

    private final Repository<T> repository; 

    public AbstractResource(Repository<T> repository) { 
     this.repository = repository; 
    } 

    @GET 
    public List<T> getAll() { 
     return this.repository.findAll(); 
    } 

    @GET 
    @Path("{id}") 
    public T getOne(@PathParam("id") long id) { 
     T result = this.repository.findOne(id); 
     if (result == null) { 
      throw new NotFoundException(); 
     } 
     return result; 
    } 

    @POST 
    public Response create(T entity, @Context UriInfo uriInfo) { 
     T saved = this.repository.save(entity); 
     // BaseEntity should have an id property 
     long id = saved.getId(); 
     URI createdUri = uriInfo.getAbsoluteUriBuilder() 
      .path(id).build(); 
     return Response.created(createdUri).build(); 
    } 
} 

您可以爲@PUT@DELET這樣做。所有資源集合的核心功能都是相同的。唯一需要改變的是Repository類型。所有的實施可能只是擴展它像

@Path("pets") 
public class PetsResource extends AbstractResource<Pet> { 

    @Inject 
    public PetsResource(PetsRepository repository) { 
     super(repository); 
    } 
} 

這是更清潔。您無需爲具體資源實施相同的基本CRUD操作。如果你想在你的具體資源類中提供其他資源方法,你可以這樣做。

相關問題