Recuperación y actualización de datos con REST

El protocolo OData requiere que todas las entidades puedan ser dirigidas por su forma canónica. Esto significa que cada entidad debe incluir la clave de la entidad particionada, la entidad raíz y la raíz de esquema.

A continuación se ofrece un ejemplo de cómo utilizar la asociación desde una entidad raíz para dirigirse a un hijo en :
/Customer('ACME')/order(100)

En WCF Data Services, la entidad hijo debe ser directamente direccionable, lo que significa que la clave en la raíz de esquema debe formar parte de la clave del hijo: /Order(customer_customerId='ACME', orderId=100). Esto se consigue creando una asociación con la entidad raíz donde la asociación de uno a uno o de muchos a uno con la entidad raíz también se identifica como una clave. Cuando las entidades se incluyen como parte de la clave, los atributos de la entidad padre se exponen como propiedades clave.

Figura 1. Diagrama del esquema de entidades Customer y Order
Diagrama del esquema de entidades Customer y Order

El diagrama de esquema de entidad Customer/Order ilustra cómo se particiona cada entidad utilizando Customer. La entidad Order incluye Customer como parte de su clave y, por lo tanto, se puede acceder a ella directamente. El servicio de datos REST expone todas las asociaciones de clave como propiedades individuales: Order tiene customer_customerId y OrderDetail tiene order_customer_customerId y order_orderId.

Utilizando la API EntityManager, puede encontrar el pedido (Order) utilizando el cliente (Customer) y el ID de cliente:

transaction.begin();
// Buscar el pedido mediante el cliente. Sólo incluimos el ID
// en la clase Customer al crear la instancia de clave OrderId.
Order order = (Order) em.find(Order.class, 
    new OrderId(100, new Customer('ACME')));
...
transaction.commit();
Al utilizar el servicio de datos REST, el pedido se puede recuperar con cualquiera de los URL:
  • /Order(orderId=100, customer_customerId='ACME')
  • /Customer('ACME')/orders?$filter=orderId eq 100

Para dirigirse a la clave de cliente se utiliza el nombre de atributo de la entidad Customer, un carácter de subrayado y el nombre de atributo del ID de cliente: customer_customerId.

Una entidad también puede incluir una entidad no raíz como componente de su clave si todos los ancestros de la entidad no raíz tienen asociaciones de clave con la raíz. En este ejemplo, OrderDetail tiene una asociación de clave con Order y Order tiene una asociación de clave con la entidad Customer raíz. Utilizando la API EntityManager:

transaction.begin();
// Construir una instancia de clave OrderDetailId. Ésta incluye
// Order y Customer con sólo el conjunto de claves.
Customer customerACME = new Customer("ACME");
Order order100 = new Order(100, customerACME);
OrderDetailId orderDetailKey = 
    new OrderDetailId(order100, "COMP");
OrderDetail orderDetail = (OrderDetail) 
    em.find(OrderDetail.class, orderDetailKey); 
...

El servicio de datos REST permite dirigirse a OrderDetail directamente:

/OrderDetail(productId=500, order_customer_customerId='ACME', order_orderId =100)

La asociación de la entidad OrderDetail a la entidad Product se ha roto para permitir particionar el inventario de pedidos (Order) y productos (Product) independientemente. La entidad OrderDetail almacena la categoría y el ID de producto en lugar de una relación estricta. Al desacoplar los dos esquemas de entidad, sólo se accede a una partición a la vez.

El esquema de entidad Category y Product, ilustrado en el diagrama, muestra que la entidad raíz es Category y que cada entidad Product tiene una asociación con una entidad Category. La entidad Category se incluye en la identidad Product. El servicio de datos REST expone una propiedad clave: category_categoryId que permite dirigirse directamente a Product.

Puesto que Category es la entidad raíz, en un entorno particionado, se debe conocer la categoría para encontrar el producto. Utilizando la API EntityManager, la transacción se debe fijar a la entidad Category antes de buscar la entidad Product.

Utilizando la API EntityManager:

transaction.begin();
// Crear la entidad raíz Category con sólo la clave. Esto nos
// permite construir un ProductId sin necesidad de encontrar
// la entidad Category en primer lugar. La transacción queda
// fijada a la partición donde se almacena Category "COMP".
Category cat = new Category("COMP");
Product product = (Product) em.find(Product.class, 
    new ProductId(500, cat)); 
...

El servicio de datos REST permite dirigirse a Product directamente:

/Product(productId=500, category_categoryId='COMP')