50

几天前,我开始使用 Google App Engine 和Google Cloud Endpoints为移动应用程序开发后端。本教程展示了端点是如何自动生成的,以及适用于 Android 的客户端库。

所以我们有我们的实体:

@Entity
public class Person implements IsSerializable{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Key key;

    private String name;
//...
} 

这个类的端点:

@Api(name = "personendpoint")
public class PersonEndpoint {

    @ApiMethod(name = "getPerson")
    public Person getPerson(@Named("id") Long id) {
...

此外,使用生成的 Android 端点库(使用 REST API),我想在服务器上添加一个用户界面,使用Google Web Toolkit (GWT)构建。但是我应该如何操作服务器端的日期呢?我可以看到不同的方法...

选项 A1:在 GWT 中添加 RPC 服务

public interface PersonServiceAsync {

    void insertPerson(Person person, AsyncCallback<Person> callback);

}

@RemoteServiceRelativePath("api")
public interface PersonService extends RemoteService {

    public Person insertPerson(Person person);

}
public class PersonServiceImpl extends RemoteServiceServlet implements PersonService{
    public Person insertPerson(Person person) {
        EntityManager mgr = getEntityManager();
        try {
            if (containsPerson(person)) {
                throw new EntityExistsException("Object already exists");
            }
            mgr.persist(person);
        } finally {
            mgr.close();
        }
        return person;
    }

        //...
}

但现在我的PersonServiceImplPersonEndpoint做的大致相同。所以我们没有遵循DRY :) 此外,不允许那个人有,com.google.appengine.api.datastore.Key所以我们必须改变我们的实体。

选项 A2:服务调用端点类

@Override
public Person insertPerson(Person person) {
    return new PersonEndpoint().insertPerson(person);
}

应该可以工作,但com.google.appengine.api.datastore.Key实体中仍然没有类型,并且由于端点正在使用CollectionResponse<Person>,我们必须将其转换Collection<Person>listPerson().

选项 B1:使用 Java 端点客户端库

我们可以将 GWT 客户端从我们的 App Engine API 后端中分离出来,并使用生成的 Java 端点客户端库。因此,我们从RemoteServiceServlet. 但是,即使 GWT 客户端和 Endpoints 在同一台服务器上或什至在同一项目中,这不会以两个请求结束吗?

GWT 客户端 --(RPC)--> GWT 服务器 --(HTTP 请求)--> App Engine 后端服务器

选项 B2:使用 JavaScript 端点客户端库

可能是最好的方法,但最终会导致大量的 JSNI。


那么最佳实践是什么?我在一个项目中找不到任何使用 Google Cloud Endpoints 和 GWT 的示例项目 :)

4

2 回答 2

12

旧的 DTO 困境。没有对错,只有对你来说足够好的。

重复自己可能是一件好事。现在您正在通过端点公开您的数据模型,这意味着您的实体的任何更改都会影响您的移动应用程序用户。假设您在服务器端重命名了一个属性 -> 每个未更新应用程序的客户端都出现故障。

安全性也是一个问题:如果您的 User 实体具有“email”属性,通过 GWT RPC 对其进行序列化将使您的用户的电子邮件几乎可用于任何 javascript 调试器。

真的是你想要的吗?

不要误会我的意思,我不喜欢那些“洋葱层”怪物应用程序,其中 80% 的代码似乎用于将对象转换为具有几乎相同属性的其他对象。

我认为正确的解决方案介于两者之间:拥有一个“客户端”模型 (DTO),由您通过 GWT RPC 和客户端端点公开的可序列化 POJO(无数据存储、ORM、JAXB 或任何注释)组成。您的 GWT servlet 实现和端点服务器将调用相同的服务,将您的客户端模型转换为实体并处理/保留它们。

通过这种方式,您可以重复使用您的代码,仍然保持简单,在您的 API 中拥有统一的接口,并允许您的内部管道在不改变客户端接口的情况下发展。

于 2014-03-21T13:27:30.420 回答
0

也许我不明白一些事情。但一切似乎(对我来说)都很容易。

  1. GWT(客户端!)不在服务器上。它是在客户端浏览器中执行的编译 Javascript。

  2. Google 插件生成 Javascript 客户端代码,该代码使用合适的 JSON 调用 Endpoint。

  3. 上面的代码可以从 GWT 中调用。

瞧?

于 2015-01-08T09:42:09.343 回答