Google app engine GWT和Google云端点
几天前,我开始使用Google App Engine和开发移动应用程序的后端。显示如何自动生成端点,以及Android客户端库 因此,我们有我们的实体:Google app engine GWT和Google云端点,google-app-engine,gwt-rpc,google-cloud-endpoints,Google App Engine,Gwt Rpc,Google Cloud Endpoints,几天前,我开始使用Google App Engine和开发移动应用程序的后端。显示如何自动生成端点,以及Android客户端库 因此,我们有我们的实体: @Entity public class Person implements IsSerializable{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Key key; private String name; //...
@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端点库(使用RESTAPI),我想在服务器上添加一个用户界面,使用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;
}
//...
}
应该可以工作,但是仍然没有com.google.appengine.api.datastore.Key
在实体中键入,并且由于端点正在使用CollectionResponse
,因此在listPerson()的情况下,我们必须将其转换为集合
选项B1:使用Java端点客户端库
我们可以从appengineapi后端分离GWT客户端,并使用生成的Java端点客户端库。因此,我们从RemoteServiceServlet
中调用REST/EndpointAPI。但是,即使GWT客户端和端点在同一台服务器上,或者甚至在同一个项目中,这不会在两个请求中结束吗
GWT客户端--(RPC)-->GWT服务器--(HTTP请求)-->AppEngine后端服务器
选项B2:使用JavaScript端点客户端库
可能是最好的方法,但最终会导致大规模JSNI
那么什么是最佳实践呢?我在一个项目中找不到任何使用谷歌云端点和GWT的示例项目:)好的DTO难题。没有对错,只有对你来说足够好的东西
重复你自己可能是一件好事。现在,您正在通过端点公开您的数据模型,这意味着您的实体的任何更改都将影响您的移动应用程序用户。假设您重命名了服务器端的一个属性->每个没有更新应用程序的客户端都会关闭
安全性也是一个问题:如果您的用户实体有一个“email”属性,那么通过GWT RPC序列化它将使您的用户电子邮件实际上可用于任何javascript调试器
这真的是你想要的吗?
别误会,我不喜欢那些“洋葱层”的怪物应用程序,在这些应用程序中,80%的代码似乎都是用来将对象转换成具有几乎相同属性的其他对象
我认为正确的解决方案介于两者之间:拥有一个由可序列化的POJO(无数据存储、ORM、JAXB或任何注释)组成的“客户机”模型(DTO),您可以通过GWT RPC和客户机端点公开该模型。
您的GWT servlet实现和端点服务器将调用同一个服务,该服务将把您的客户机模型转换为实体并处理/持久化它们
通过这种方式,您可以重用代码,仍然保持简单,在您的API中有一个统一的接口,并允许您的内部管道在不改变客户端接口的情况下不断发展。也许我不明白什么。
但(对我来说)一切似乎都很容易
GWT(客户端!)不在服务器上。它是在客户端浏览器中编译并执行的Javascript
Google插件生成Javascript客户端代码,用合适的JSON调用端点
以上代码可以从GWT调用
瞧 你看到了吗?是的,但它们是早期的Alpha版本,适用于googleapi。我说的是您自己的API/端点,由GAE生成。该库适用于任何基于发现的API,而您的API/端点恰好是(基于发现的)。我也面临同样的困境。我们希望使用端点API,但开发GWT前端。我有一种感觉,它可能是一个或另一个…也在寻找解决办法。现在使用JSNI.Yepp,所以这将是选项B2。但正如我所提到的,它会起作用,但最终会产生很多JSNI。因为客户端的大部分是用Java(GWT)编写/定义的,但是调用端点的逻辑是生成的Javascript代码。虽然我很长时间没有使用GWT,但我经常遇到类似的困境(商业模式与DTO)。早在2014年,这个答案并没有真正让我满意。但是,在经历了多年的高级Java开发和数千行代码之后,我必须说,你当时的评论正好抓住了要点,我完全同意你的观点。
@Override
public Person insertPerson(Person person) {
return new PersonEndpoint().insertPerson(person);
}