google-app-engine - the - google cloud api manager
GWT y Google Cloud Endpoints (2)
El buen viejo dilema de DTO. No existe el bien o el mal, solo lo que es lo suficientemente bueno para ti.
Repetirse puede ser algo bueno. En este momento está exponiendo su modelo de datos a través de su endpoint, lo que significa que cualquier cambio de sus Entidades tendrá un impacto en los usuarios de su aplicación móvil. Digamos que renombra un atributo en el lado del servidor -> cada cliente que no ha actualizado la aplicación se cae.
La seguridad también es un problema: si su entidad de usuario tiene una propiedad de "correo electrónico", serializarla a través de GWT RPC hará que el correo electrónico de su usuario esté prácticamente disponible para cualquier depurador de JavaScript.
¿Es realmente lo que quieres?
No me malinterpreten, no soy fan de las aplicaciones monstruosas de "capas de cebolla" donde el 80% del código parece estar hecho para transformar objetos en otros objetos con virtualmente las mismas propiedades.
Creo que la solución correcta es intermedia: tener un modelo de "cliente" (DTO), hecho de POJO serializables (sin almacén de datos, ORM, JAXB, cualquier anotación) que exponga a través de GWT RPC y puntos finales del cliente. Su implementación de servlet GWT y el servidor de punto final llamarían al mismo servicio que transformará su modelo de cliente en entidades y las procesará / persistirá.
De esta forma, puede reutilizar su código, aún así mantenerlo simple, tener una interfaz uniforme entre sus API y permitir que su plomería interna evolucione sin alterar las interfaces del cliente.
Hace unos días comencé a desarrollar un Backend para aplicaciones móviles usando Google App Engine y Google Cloud Endpoints . Este tutorial muestra cómo los puntos finales se generan automáticamente, así como también la biblioteca cliente para Android.
Entonces tenemos nuestra Entidad:
@Entity
public class Person implements IsSerializable{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Key key;
private String name;
//...
}
Y el punto final para esta clase:
@Api(name = "personendpoint")
public class PersonEndpoint {
@ApiMethod(name = "getPerson")
public Person getPerson(@Named("id") Long id) {
...
Además, utilizando la Biblioteca de Endpoints de Android generada (que usa la API de REST) me gustaría agregar una Interfaz de usuario en el Servidor, compilar con Google Web Toolkit (GWT) . ¿Pero cómo debo manipular la fecha en el lado del servidor? Puedo ver diferentes enfoques ...
Opción A1: Agregar un servicio RPC en 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;
}
//...
}
Pero ahora mi PersonEndpoint
y PersonEndpoint
hacen más o menos lo mismo. Por lo tanto, no seguimos DRY :) Además, esa Persona no puede tener com.google.appengine.api.datastore.Key
por lo que tendríamos que cambiar nuestras Entidades.
Opción A2: Llamadas de servicio clase de punto final
@Override
public Person insertPerson(Person person) {
return new PersonEndpoint().insertPerson(person);
}
Debería funcionar, pero todavía no com.google.appengine.api.datastore.Key
Escriba en la entidad y como los listPerson()
están utilizando CollectionResponse<Person>
tendremos que transformar esto en una Collection<Person>
en el caso de listPerson()
.
Opción B1: Uso de la biblioteca de Java Endpoint Client
Podríamos dividir el cliente de GWT de nuestro motor de la API de App Engine y usar las bibliotecas de Endpoint Client generadas para Java. Así que llamamos a REST / Endpoint-API desde un RemoteServiceServlet
. Pero, ¿no terminaría esto en dos solicitudes, incluso si el cliente GWT y los puntos finales están en el mismo servidor o incluso en el mismo proyecto?
Cliente GWT - (RPC) -> Servidor GWT - (Solicitud HTTP) -> Servidor de fondo de App Engine
Opción B2: uso de la biblioteca de JavaScript Endpoint Client
Podría ser el mejor enfoque, pero terminaría en JSNI masivo.
Entonces, ¿cuál es la mejor práctica? No puedo encontrar proyectos de ejemplo con Google Cloud Endpoints Y GWT en un solo proyecto :)
Tal vez no entiendo algo. Pero todo parece (para mí) ser muy fácil.
GWT (¡cliente!) No está en el servidor. Es compilado Javascript ejecutado en el navegador del cliente.
El complemento de Google genera un código de cliente Javascript que llama a Endpoint con JSON adecuado.
El código anterior se puede llamar desde GWT.
Voila?