BreezeJS on Durandal with PHP REST API (Laravel)
Asked Answered
L

2

2

I'm writing a SPA in Durandal 2.1. So far so good. However, I'm having great difficulties in selecting the right Data Persistence library to communicate with my PHP (Laravel) REST API.

The number one library for Durandal is BreezeJS. It is said that it supports API's without oData / ASP.NET Entity framework. I've searched for many days now, but I can't find any decent resource telling me how to use BreezeJS with my basic PHP REST API.

The wish-list is as follows:

  • Persist data between views
  • Validate Models
  • State tracking (a.k.a. isDirty / cancelChanges)
  • GET/POST/PUT/DELETE using REST API calls (in case of PUT, only send the dirty stuff)

The REST API is as follows. I'll use a Contact + Address + Country Model structure to explain how my API works.

  • Contact many-to-many Address
  • Address belongs-to Country a.k.a. Country has-many Address

The following GET-request:

GET /api/v1/contacts
+ Payload:
{
    append_addresses         : 1, // add addresses as nested data
    append_addresses_country : 1, // add country as nested data of addresses
    stack                    : 2, // return no more than 2 contacts (e.g. for pagination)
    page                     : 1, // return the first page (so the first 2 contacts)
    count                    : 1  // return the total number of existing contacts
}

Returns the following result:

{
    "total": 100,
    "data": [
        {
            "id": 1,
            "name": "Turner PLC",
            "addresses": [
                {
                    "id"         : 214,
                    "country_id" : 1,
                    "city"       : "North Jason",
                    "country"    : {
                        "id"        : 1,
                        "name"      : "Canada"
                    }
                },
                {
                    "id"         : 203,
                    "country_id" : 2,
                    "city"       : "West Lafayette",
                    "country"    : {
                        "id"        : 2,
                        "name"      : "The Netherlands"
                    }
                }
            ]
        }
    ]
}

The API supports 2 ways to use POST/PUT:

  1. POST/PUT data in the same structure as displayed above under the "data" attribute. Based on the id of a Model, the backend will decide if it needs to create OR update a Model. The backend also automatically detects if it needs to create/update/delete relationships, based on the supplied payload. Pretty cool, huh? :-)

  2. POST /api/v1/entities...

... with the following Payload:

[
    {
        "type" : "Contact",
        "data" : {
            "id"   : null, // Will create a new Contact
            "name" : "Malaysia"
        }
    },
    {
        "type" : "Contact",
        "data" : {
            "id"   : 1, // Will update existing Contact
            "name" : "Turner Example"
        }
    },
    {
        "type" : "Address",
        "data" : {
            "id"          : 203, // Will update existing Address
            "city"        : "South Jason",
            "contacts_id" : [1,3,5] // Will set/update the many-to-many relationship between Address ID 203 and Contact ID 1, 3 and 5
        }
    }
]

So now the questions I have:

  1. Can this be done in BreezeJS or should I consider an alternative like JayData or Waterline?

  2. BreezeJS seems te insist using a query like syntax. Am I missing its purpose or is it useless? If so, is it possible to omit the query like syntax and still use BreezeJS or an alternative?

  3. How will BreezeJS (or the alternative) deal with the hasOne, hasMany, belongsTo and belongsToMany and Polymorphic relationships?

  4. Does a "getting started" exist for a similar use case as mine? I've read a lot about BreezeJS and its alternatives, but the pieces of the puzzle are not coming together in my mind yet. In other words, I'm completely lost.

Lp answered 7/8, 2014 at 11:38 Comment(0)
S
3

There are plenty of samples at http://www.breezejs.com/samples that show using Breeze.js without EF and OData. Choose your flavor, I would recommend Zza, Intro to SPA (Ruby), Edmunds, or ESPN sample. They all use client-side metadata from what I recall.

As far as POSTing data feel free to either customize the AJAX adapter using something like http://www.breezejs.com/documentation/breezeajaxpostjs which allows POSTing data and Breeze will still interpret the results as entities given they are in a proper JSON structure or you can always either extend the current AJAX adapter Breeze supplies with your own augmentations or just use plain old AJAX calls. It really doesn't matter.

Keep in mind that Breeze doesn't prefer how you get/set your data only that you do so and update the entities that it has cached with the results. To specifically answer your questions -

  1. Can this be done in BreezeJS or should I consider an alternative like JayData or Waterline? Should I use this or that? - Not an easy question to answer. Always choose the best tool for the job.

  2. BreezeJS seems te insist using a query like syntax. Am I missing its purpose or is it useless? If so, is it possible to omit the query like syntax and still use BreezeJS or an alternative? By default Breeze uses the syntax in queries because the default adapter is the WebAPI one. Feel free to use the .withParameters() method to create our own query bodies.

  3. How will BreezeJS (or the alternative) deal with the hasOne, hasMany, belongsTo and belongsToMany and Polymorphic relationships? Breeze supports all relationships and types except for many-to-many. Many-to-many relationships can be supported with a junction type object though. http://www.breezejs.com/documentation/presenting-many-many

  4. Does a "getting started" exist for a similar use case as mine? I've read a lot about BreezeJS and its alternatives, but the pieces of the puzzle are not coming together in my mind yet. In other words, I'm completely lost. Read the docs and check out the samples above. There are links in some of the samples to a walk-thru, I am the author of the ESPN one so I know that it works and is unconcerned with the API implementation

Shiner answered 7/8, 2014 at 14:4 Comment(0)
L
1

What he said. (PW Kad)

Regarding the over-the-wire query syntax, Breeze uses OData syntax out-of-the-box, but can be adapted to a more RESTy syntax. Take a look at breeze.ajaxrestinterceptor.js. It converts the default OData syntax, e.g.:

/breeze/orders/?$filter=id eq 1

into RESTy syntax:

/breeze/orders/1

If you want to support richer queries, breeze.server.php does that for you, but it currently supports only the Doctrine ORM. You might be able to adapt it for Laravel/Eloquent.

There's also a demo using breeze.server.php that you might want to browse through.

Libration answered 7/8, 2014 at 21:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.