Objectify with Cloud Endpoints

后端 未结 4 801
暖寄归人
暖寄归人 2021-02-01 22:17

I am using appengine cloud endpoints and objectify. I have previously deployed these endpoints before and now I am updating them and it is not working with Objectify. I have m

相关标签:
4条回答
  • 2021-02-01 22:37

    Others already mentioned how to approach this with @ApiResourceProperty and @ApiTransformer. But I do need the key available in client-side, and I don't wanna transform the whole entity for every one. I tried replacing the Objectify Key with com.google.appengine.api.datastore.Key, and it looks like it worked just fine as well in my case, since the problem here is mainly due to that endpoint does not support parameterized types.

    0 讨论(0)
  • 2021-02-01 22:38

    Because of the popularity of Objectify, a workaround was added in prior releases to support the Key type, until a more general solution was available. Because the new solution is available, the workaround has been removed. There are two ways you can now approach the issue with the property.

    1. Add an @ApiResourceProperty annotation that causes the key to be omitted from your object during serialization. Use this approach if you want a simple solution and don't need access to the key in your clients.
    2. Add an @ApiTransformer annotation that provides a compatible mechanism to serialize/deserialize the field. Use this approach if need access to the key (or a representation of it) in your clients. As this requires writing a transformer class, it is more work than the first option.
    0 讨论(0)
  • 2021-02-01 22:53

    I came up with the following solution for my project:

    @Entity
    public class Car {
    
        @Id Long id;
    
        @ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
        Key<Driver> driver;
    
        public Key<Driver> getDriver() {
            return driver;
        }
    
        public void setDriver(Key<Driver> driver) {
            this.driver = driver;
        }
    
        public Long getDriverId() {
            return driver == null ? null : driver.getId();
        }
    
        public void setDriverId(Long driverId) {
            driver = Key.create(Driver.class, driverId);
        }
    }
    
    @Entity
    public class Driver {
        @Id Long id;
    }
    

    I know, it's a little bit boilerplate, but hey - it works and adds some handy shortcut methods.

    0 讨论(0)
  • 2021-02-01 22:54

    At first, I did not understand the answer given by Flori, and how useful it really is. Because others may benefit, I will give a short explanation.

    As explained earlier, you can use @ApiTransformer to define a transformer for your class. This would transform an unserializable field, like those of type Key<myClass> into something else, like a Long.

    It turns out that when a class is processed by GCE, methods called get{fieldName} and set{FieldName} are automatically used to transform the field {fieldName}. I have not been able to find this anywhere in Google's documentation.

    Here is how I use it for the Key{Machine} property in my Exercise class:

    public class Exercise {
      @ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
      public Key<Machine> machine;
      // ... more properties
    
      public Long getMachineId() {
        return this.machine.getId();
      }
    
      public void setMachineId(Long machineId) {
        this.machine = new Key<Machine>(Machine.class, machineId);
      }
    
      // ...
    }
    
    0 讨论(0)
提交回复
热议问题