GWT和Google Cloud Endpoints [英] GWT and Google Cloud Endpoints

查看:123
本文介绍了GWT和Google Cloud Endpoints的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



所以我们有我们的实体:

  @Entity 
public class Person实现IsSerializable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
私钥键;

私人字符串名称;
// ...
}

此类的端点:

  @Api(name =personendpoint)
public class PersonEndpoint {

@ ApiMethod(name =getPerson)
public Person getPerson(@Named(id)Long id){
...
添加用户界面,使用 strong> Google Web Toolkit(GWT)。但我应该如何操纵服务器端的日期?我可以看到不同的方法......



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

  public interface PersonServiceAsync {

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


$ b @RemoteServiceRelativePath(api)
public interface PersonService extends RemoteService {
$ b $ public Person insertPerson(Person person);

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

// ...
}



<但现在我的 PersonServiceImpl PersonEndpoint 大致相同。所以我们没有遵循 DRY :)此外,该人不允许有 com.google.appengine.api.datastore.Key ,因此我们必须更改实体。



选项A2:服务调用终端类

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

应该可以工作,但仍然没有 com.google。 appengine.api.datastore.Key 键入实体,并且由于终结点正在使用 CollectionResponse< Person> ,我们必须将其转换为<$如果 listPerson()



c $ c> Collection< Person> 选项B1:使用Java端点客户端库



我们可以将GWT客户端从我们的App Engine API后端拆分出来,并使用生成的端点客户端库对于Java。所以我们从 RemoteServiceServlet 中调用REST / Endpoint-API。但是,即使GWT客户端和端点在同一台服务器上,或者甚至在同一个项目中,这两个请求都不会结束吗?


$ b

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



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

可能是最好的方法,但会最终成为大规模的JSNI。






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

解决方案

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



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



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



它真的是你想要的吗? b
$ b

不要误解我的意思,我不是那些洋葱层怪物应用程序的粉丝,其中80%的代码似乎用于转换对象我认为正确的解决方案介于两者之间:有一个客户模型(DTO),由可序列化的POJO(没有数据存储区)组成,ORM,JAXB,无论注释)通过GWT RPC和客户端端点公开。
您的GWT servlet实现和Endpoint服务器将调用相同的服务,将您的客户端模型转换为实体并处理/保留它们。



这样,您可以重用您的代码,仍然保持简单,拥有统一的API接口,并且允许您的内部管道工程发展而不改变客户端接口。


A few days ago I've started developing a Backend for Mobile Applications using Google App Engine and Google Cloud Endpoints. This tutorial shows how the endpoints are getting generated automatically, as well as the client library for Android.

So we have our Entity:

@Entity
public class Person implements IsSerializable{

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

    private String name;
//...
} 

And the endpoint for this class:

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

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

Besides, using the generated Android Endpoint Library (that uses the REST API) I would like to add a User Interface on the Server, build with Google Web Toolkit (GWT). But how should I manipulate the date on Server Side? I can see different approaches...

Option A1: Adding an RPC Service in GWT

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;
    }

        //...
}

But now my PersonServiceImpl and PersonEndpoint do roughly the same. So we didn't follow DRY :) Besides, that Person is not allowed to have com.google.appengine.api.datastore.Key so we would have to change our Entities.

Option A2: Service calls endpoint class

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

Should work , but still no com.google.appengine.api.datastore.Key Type in the Entity and since Endpoints are using CollectionResponse<Person> we would have to transform this into an Collection<Person> in case of listPerson().

Option B1: Using the Java Endpoint Client Library

We could split the GWT Client from our App Engine API Backend and use the generated Endpoint Client Libraries for Java. So we call the REST/Endpoint-API from within a RemoteServiceServlet. But wouldn't this end up in two Requests, even if the GWT client and Endpoints are on the same server or even in the same project?

GWT Client --(RPC)--> GWT Server --(HTTP Request)--> App Engine Backend Server

Option B2: Using the JavaScript Endpoint Client Library

Might be the best approach but would end up in massive JSNI.


So what's best practice? I can't find any example projects using Google Cloud Endpoints AND GWT in one project :)

解决方案

The good old DTO dilemma. There is no right or wrong, just what is good enough for you.

Repeating yourself can be a good thing. Right now you are exposing your data model through your endpoint, which means that any change of your Entities will impact your mobile app users. Let's say you rename an attribute on the server side -> every client who has not updated the app goes down.

Security is also an issue : if your User entity has an "email" property, serializing it through GWT RPC will make your user's email virtually available to any javascript debugger.

Is it really what you want?

Don't get me wrong, I'm not a fan of those "onion layers" monster apps where 80% of the code seems to be made to transform objects into other objets with virtually the same properties.

I think the right solution is in between: having a "client" model (DTOs), made of serializable POJOs (no datastore, ORM, JAXB, whatever annotation) that you expose through both GWT RPC and Client Endpoints. Your GWT servlet implementation and the Endpoint server would call the same service that will transform your client model into entities and process/persist them.

This way you can reuse your code, still keep it simple, have a uniform interface accross your APIs, and allow your inner plumbering to evolve without altering the client interfaces.

这篇关于GWT和Google Cloud Endpoints的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆