GWT和Google Cloud端点

时间:2013-05-28 07:51:22

标签: google-app-engine gwt-rpc google-cloud-endpoints

几天前,我开始使用Google App Engine和Google Cloud Endpoints开发移动应用后端。 This tutorial显示了如何自动生成端点,以及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端点客户端库

我们可以从我们的App Engine API后端拆分GWT客户端,并使用生成的Endpoint Client Libraries for Java。所以我们在RemoteServiceServlet内调用REST / Endpoint-API。但即使GWT客户端和端点在同一台服务器上,甚至在同一个项目中,这最终会不会出现在两个请求中?

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

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

可能是最好的方法,但最终会出现在大规模的JSNI中。


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

2 个答案:

答案 0 :(得分:12)

旧的DTO困境。没有对错,只有对你有用的东西。

重复自己可能是一件好事。现在,您通过终端公开您的数据模型,这意味着您的实体的任何更改都会影响您的移动应用程序用户。我们假设你在服务器端重命名一个属性 - &gt;每个未更新应用程序的客户都会失败。

安全性也是一个问题:如果您的用户实体有一个&#34;电子邮件&#34;属性,通过GWT RPC序列化将使您的用户的电子邮件几乎可用于任何JavaScript调试器。

这真的是你想要的吗?

不要误会我的意思,我不是那些&#34;洋葱层&#34;的粉丝。怪物应用程序,其中80%的代码似乎是将对象转换为具有几乎相同属性的其他对象。

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

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

答案 1 :(得分:0)

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

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

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

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

  4. 瞧?