jsonRest сложные структуры с додзё - PullRequest
3 голосов
/ 10 ноября 2011

Я занимаюсь разработкой веб-приложения на основе среды dojo.

Я решил использовать dojox.data.JsonRestStore для связи с сервером.

Например, у меня есть это представление Order (ecommerce) в Json:

{
id: int,
name: str,
date: str,
items: [
    {
        id: int,
        name: str,
        pcs: int,
        price: int,
        total: int

    }, ...
]
}

Order имеет некоторые основные атрибуты (id, name, date), а также содержит массив упорядоченных элементов.,

Я не уверен, что это хороший (REST) ​​дизайн, и мне интересно, должны ли заказанные элементы быть в отдельном ресурсе (и так в отдельном jsonRestStore).

Я думаю, что могувозникают проблемы с текущей объектной моделью, когда я хочу отобразить базовые атрибуты Orders в форме dojo и упорядоченные элементы в djo datagrid.

Итак, мой вопрос, подходит ли мой текущий подход к созданию клиентского приложения REST?Кроме того, как правильно реализовать мою примерную форму с помощью datagrid в dojo?

Ответы [ 2 ]

3 голосов
/ 13 ноября 2011

Хотя ваш дизайн RESTful и в архитектуре REST нет ничего, что требовало бы этого, я думаю, что большинство людей согласятся с тем, что разделение ваших ресурсов - лучший путь. Если вы проверяете Restful Web Services , они описывают это как ресурсно-ориентированную архитектуру.

Я разработал пример, который хранит заказы и элементы в отдельных JsonRestStores и позволяет вам отображать объект Order через форму Dojo, а элементы заказа - через Dojo DataGrid. Я думаю, что код прост, и я также добавил несколько комментариев в код, чтобы попытаться прояснить ситуацию.

Я создал простой бэкэнд ASP.NET MVC 3, чтобы предоставить некоторые фиктивные данные для примера. Я также опубликовал этот код, хотя вас действительно интересует только часть кода «Просмотр», код бэкэнда также может помочь вам выяснить или изменить любой код бэкенда, который у вас есть.

Вид:

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
   <title>JsonRestStore Datagrid Example</title>

<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.6.1/dojo/resources/dojo.css"/>
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.6.1/dijit/themes/tundra/tundra.css"/>
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.6.1/dojox/grid/resources/Grid.css"/>
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.6.1/dojox/grid/resources/tundraGrid.css"/>

<script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/dojo/1.6.1/dojo/dojo.xd.js' djConfig="parseOnLoad:true"></script>

<script type="text/javascript">

    dojo.require("dojox.data.JsonRestStore");
    dojo.require("dojox.grid.DataGrid");
    dojo.require("dijit.form.DateTextBox");
    dojo.require("dojox.grid.cells.dijit");
    dojo.require("dojo.date.locale");
    var item_structure = null;

    dojo.ready(function () {
        setItemTableStructure();
        //retrieve a single order
        //expects json to look like
        // {"Id":2,"Name":"Order Name 2","Date":"\/Date(1321135185260)\/","Items":{"Ref":"/Order/2/Items"}}
        order_store = new dojox.data.JsonRestStore({ target: "/Order/2", idAttribute: "Id" });

        order_store.fetch({
            onComplete: function (item) {
                //this method is called after an item is fetched into the store
                //item here is the order json object
                var orderId = new dijit.form.TextBox({ value: order_store.getValue(item, 'Id') }, 'orderId');
                var orderName = new dijit.form.TextBox({ value: order_store.getValue(item, 'Name') }, 'orderName');
                var orderDate = new dijit.form.DateTextBox({ value: parseJsonDate(order_store.getValue(item, 'Date')) }, 'orderDate');
                var items = order_store.getValue(item, 'Items').Ref;

                //make a call to retrieve the items that are contained within a particular order
                //expects a json object that looks like
                //[{"Ref":"/Item/1"},{"Ref":"/Item/2"},{"Ref":"/Item/3"},{"Ref":"/Item/4"},{"Ref":"/Item/5"}]
                var xhrArgs = {
                    url: items,
                    handleAs: "json",
                    load: loadOrder, //main method
                    error: function (error) {
                        console.log(error);
                    }
                }
                var deferred = dojo.xhrGet(xhrArgs);
            }
        });
    });

    //This is the main method
    function loadOrder(data) {
        var itemIds = "";
        dojo.forEach(data, function(item, i){
            itemIds += item.Ref.charAt(item.Ref.length-1);
            itemIds += ",";
        });
        itemIds = itemIds.substring(0, itemIds.length-1);

        //build the backend to accept a comma seperated list of item ids
        //like    /Item/1,2,3
        item_store = new dojox.data.JsonRestStore({target:"/Item/" + itemIds, idAttribute:"Id"});
        items = new dojox.grid.DataGrid({
            name: "items",
            formatter: function(date) {
                        if (date) return dojo.date.locale.format(parseJsonDate(date), {
                            selector: "Date"
                        })
                    },
            structure: item_structure,
            store: item_store
        }, dojo.byId('orderItems'));

        items.startup();
    }

    function setItemTableStructure() {
        item_structure = [
        { 
          field: 'Id'
        },
        {
          field: 'Name'
        },
        {
          field: 'Price'
        },
        {
            field: 'Date',
            type: dojox.grid.cells.DateTextBox,
            widgetProps: {
                selector: "Date"
            },
            formatter: function(v) {
                if (v) return dojo.date.locale.format(parseJsonDate(v), {
                    selector: 'Date'
                })
            }
        }];
    }

    function parseJsonDate(jsonDate) {
        var offset = new Date().getTimezoneOffset() * 60000;
        var parts = /\/Date\((-?\d+)([+-]\d{2})?(\d{2})?.*/.exec(jsonDate);

        if (parts[2] == undefined)
          parts[2] = 0;

        if (parts[3] == undefined)
          parts[3] = 0;

        return new Date(+parts[1] + offset + parts[2]*3600000 + parts[3]*60000);
    }
  </script>
  </head>
  <body>
    <h1>Json Rest Store with DataGrid Example</h1><br />

    <form style='margin: 10px' action='post'>
    <h2>Order</h2>
    <input id='orderId' />
    <input id='orderName' />
    <input id='orderDate' />
    </form>
    <h2>Items</h2>
    <div id='orderItems'></div>
    </body>
 </html>

Модель:

using System;

namespace OrdersRestService.Models
{
    public class Item
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public double Price { get; set; }
        public DateTime Date { get; set; }
    }
}

public class Order
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime Date { get; set; }
    public Reference Items { get; set; }
}

public class Reference
{
    public string Ref { get; set; }
}

Контроллеры:

namespace OrdersRestService.Controllers
{
    public class OrderController : Controller
    {
        public ActionResult Index(string id)
        {
            Order order = new Order
                              {
                                  Id = Convert.ToInt32(id),
                                  Name = "Order Name " + id,
                                  Date = DateTime.Now,
                                  Items = new Reference
                                                {
                                                    Ref = "/Order/" + id + "/Items"
                                                }
                              };

            return Json(order, JsonRequestBehavior.AllowGet);
        }

        public ActionResult Items()
        {
            List<Reference> items = new List<Reference>();

            for (int i = 1; i <= 5; i++)
            {
                Reference r = new Reference();
                r.Ref = "/Item/" + i;
                items.Add(r);
            }

            return Json(items, JsonRequestBehavior.AllowGet);
        }
    }

    public class ItemController : Controller
    {
        public ActionResult Index(string id)
        {
            List<Item> items = new List<Item>();
            foreach (string itemid in id.Split(','))
            {
                Item item = new Item 
                                  {
                                      Id = Convert.ToInt32(itemid),
                                      Name = "Item Name " + itemid,
                                      Date = DateTime.Now,
                                  };
                items.Add(item);
            }

            return Json(items, JsonRequestBehavior.AllowGet);
        }
    }

    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }
    }
}

Global.aspx.cs

public class MvcApplication : System.Web.HttpApplication
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
    }

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            "DefaultWithAction", // Route name
            "{controller}/{id}/{action}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
        );
    }

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);
    }
}
1 голос
/ 10 ноября 2011

Ваш подход в порядке. Клиент REST не должен знать, как хранятся данные, будь то в реляционной базе данных или в текстовом файле. Вы обязательно можете включить элементы заказа при публикации в конечной точке заказа. Этот дизайн быстрее и имеет меньше запросов к серверу. Вместо того, чтобы публиковать один раз для создания заказа, ждать идентификатора заказа и затем публиковать все элементы впоследствии, вы публикуете один раз со всем.

REST - это использование существующих HTTP-глаголов, таких как POST, DELETE, GET, PUT и других, для упрощения ваших конечных точек. Идея состоит в том, чтобы использовать протокол HTTP как часть интерфейса вашего приложения. Он не определяет, как должна быть разработана ваша модель.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...