The data layer

The shopping application needs to be supplied with the following data:

  • A list of categories
  • A list of products, filtered by category and sorted by the selected criteria
  • Details of a single product

This makes things pretty straightforward. So, in a moment, we'll break down exactly what sort of data responses we'll see when we make a server request.

Before this, you might notice that we're skipping over the part of the application that will integrate with the server-side. The key reason for this is that it will add complexity to our example application without adding much more value; we want to highlight the decisions that we made in order to piece together this application and do it in a concise and understandable way. While there are many features we can add to this application and indeed our previous examples, we want to make sure that the really important aspects of building an application can shine through.

Let's go back to the data that we'd like our backend to supply. Firstly, retrieving a list of categories:

GET: /category
Accepts: N/A
Returns: [{"id":1,"name":"Pilsner"},{"id":2,"name":"IPA"}]

It accepts no parameters and returns a JSON array containing the ID and name of each available category. To see the products in a category, we talk to the products API:

GET: /product
Accepts:
sort = [{"property":"id","direction":"ASC"}]
filter = [{"property":"categoryId","value":2}]
Returns: [{"id":1,"name":"Sierra Nevada Torpedo Extra IPA","price":"19.99", "imagePath":"snte1.jpg"}]

It returns an array of objects, each containing the properties needed to render a product list item. The array can be filtered by passing a sort query parameter with a JSON array of fields to sort against, and we fetch only the category of products we need by passing a filter query parameter with a JSON array. This array contains one object to filter the categoryId property. This JSON filter and sort approach is one we've used in the past and it fits well with the way Ext JS works on the client side.

Finally, we have the request for the details of a single product as follows.

GET: /product/:id
Accepts: N/A
Returns: { "id": 1, <all product fields omitted> }

It does not accept any query parameters per se. Instead, the ID is passed as part of the URL path, as it's more often seen in a RESTful API. The full JSON response is omitted for brevity, but it returns the full set of fields required to populate the product window.

Now that we've gathered this information, we can start to think about how it will shape our data classes.

Information contemplation

Based on the API we've just described, we have two main models and their associated stores:

Alcohology.model.Product: extends Alcohology.model.BaseModel
- id
- name
- imagePath
- description
- price
- previousPrice
- brewery
- features
- categoryId

Alcohology.model.Category: extends Alcohology.model.BaseModel
- id
- name

These will have accompanying stores that do nothing more than wrap their model. In addition to the classes that interact with the API, we'll have a couple more to deal with some other moving parts in the application. Firstly, we'll look at the various items in the cart:

Alcohology.model.CartItem: extends Alcohology.model.BaseModel
- productId
- productName
- price
- quantity

An alternative to this design will be to hold only productId and quantity and look up the product details from the product store at render time. However, the method we've chosen makes the resulting code simpler and it also allows you to store data such as the price at the time the user adds it to the cart. This can be handy in complex or busy sites if the product price changes after the user adds it to the cart.

Secondly, we have a model to hold an order:

Alcohology.model.Order: extends Alcohology.model.BaseModel
- date
- totalCost
- items[]
    - productId
    - productName
    - price
    - quantity

This will be used to represent a shopping cart that has been converted to an order. While this class will be consumed by a simple wrapper store, CartItem will have a store that does a little bit more:

Alcohology.store.Cart: extends Ext.data.Store
- addProduct
- toOrder

The addProduct method can be passed to a product model that is to be added to the cart. It adds a bit of logic to detect whether a matching product already exists in the cart; if it does, it increments the quantity rather than creating a new cart item.

The toOrder method converts the cart and all its items to an Order model, which can then be saved to the server.

The API for this project is simple, but we'll also use models and stores to organize our data and application state in memory, favoring the Ext.data classes over standard JavaScript objects in order to leverage their powerful features. With the data design pretty much complete, we can move on to see how this data will interact with the rest of the application.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset