GWT и конечные точки Google Cloud - программирование
Подтвердить что ты не робот

GWT и конечные точки Google Cloud

Несколько дней назад я начал разработку Backend для мобильных приложений с помощью Google App Engine и конечных точек Google Cloud. В этом руководстве показано, как создаются конечные точки автоматически, а также клиентская библиотека для Android.

Итак, у нас есть наш Entity:

@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: добавление службы RPC в 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;
    }

        //...
}

Но теперь мои PersonServiceImpl и PersonEndpoint делают примерно то же самое. Таким образом, мы не следовали 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 Введите Entity и, поскольку Endpoints используют CollectionResponse<Person>, нам пришлось бы преобразовать это в Collection<Person> в случае listPerson().

Вариант B1: Использование клиентской библиотеки конечных точек Java

Мы могли бы разделить GWT-клиент из нашего API-интерфейса API App Engine и использовать созданные клиентские библиотеки конечных точек для Java. Поэтому мы вызываем REST/Endpoint-API из RemoteServiceServlet. Но разве это не будет в двух запросах, даже если клиент GWT и конечные точки находятся на одном сервере или даже в одном проекте?

Клиент GWT - (RPC) → Сервер GWT - (HTTP-запрос) → Сервер резервного сервера приложений

Вариант B2: использование клиентской библиотеки конечных точек JavaScript

Возможно, это лучший подход, но в конечном итоге окажется в массивном JSNI.


Так какая лучшая практика? Я не могу найти примеры проектов с использованием Google Cloud Endpoints AND GWT в одном проекте:)

4b9b3361

Ответ 1

Хорошая старая дилемма DTO. Нет никакого правильного или неправильного, только то, что достаточно для вас.

Повторение себя может быть хорошим. Прямо сейчас вы подвергаете свою модель данных своей конечной точке, а это означает, что любое изменение ваших объектов повлияет на пользователей мобильных приложений. Скажем, вы переименовываете атрибут на стороне сервера → каждый клиент, который не обновил приложение, опускается.

Безопасность также является проблемой: если ваш пользовательский объект имеет свойство "email", сериализация его через GWT RPC сделает вашу электронную почту пользователя практически доступной для любого отладчика javascript.

Это действительно то, что вы хотите?

Не поймите меня неправильно, я не поклонник этих "монстров" лунных слоев, где 80% кода, похоже, сделано для преобразования объектов в другие объекты с практически теми же свойствами.

Я думаю, что правильное решение находится между ними: наличие "клиентской" модели (DTO), сделанной из сериализуемых POJO (без данных, ORM, JAXB, любой аннотации), которые вы просматриваете как через GWT RPC, так и в Endpoints клиента. Ваша реализация сервлета GWT и сервер конечной точки будут вызывать одну и ту же службу, которая преобразует вашу модель клиента в объекты и обрабатывает/сохраняет их.

Таким образом, вы можете повторно использовать свой код, по-прежнему держать его простым, иметь унифицированный интерфейс по вашим API-интерфейсам и позволить вашему внутреннему водопроводчику развиваться без изменения клиентских интерфейсов.

Ответ 2

Может, я ничего не понимаю. Но все кажется мне очень легко.

  • GWT (клиент!) не находится на сервере. Он скомпилирован Javascript, выполненный в клиентском браузере.

  • Плагин Google генерирует код клиента Javascript, который вызывает конечную точку с подходящим JSON.

  • Выше код можно вызывать из GWT.

Voila?