Datajs: javascript bibliotheek speciaal voor browser data

Voor mij is jQuery een verademing. Waar in het verleden het manipuleren van
objecten in de DOM van de browser een lastige bezigheid was, vooral als de
pagina dynamisch opgebouwd wordt, kan met jQuery zo’n klusje snel geklaard zijn. En jQuery is dan ook vooral populair vanwege die goede eigenschappen om door de DOM te navigeren.

odata

Momenteel ben ik bezig met een andere javascript bibliotheek, datajs

Datajs wilt DE oplossing worden voor ‘data-centric’ webapplicaties, op de browser welteverstaan. Met datajs moet het ophalen en wegschrijven van data eenvoudig, snel en transparant worden.  Hoewel met jQuery ook heel prettig ajax calls uitgevoerd kunnen worden, heeft datajs wel degelijk meerwaarde.

Op dit moment wordt eigenlijk alleen OData ondersteund. Dit is het formaat wat een WCF Data Service communiceert. Zo’n service is ook netjes met b.v. jQuery aan te spreken maar dit is net wat bewerkelijker en beperkter.

Het is bewerkelijk omdat communicatie tussen javascript client en OData service graag in Json formaat wordt uitgevoerd. Datajs snapt dit direct, voor jQuery moet je de objecten eerst naar Json serialiseren via Json stringify. En datajs kan ook op een elegante manier meerdere call tegelijkertijd als batch versturen. Dit scheelt gebruik van bandbreedte en maakt het omgaan met meerdere asynchrone callbacks overbodig.

Helaas bevindt datajs zich nog in een vroeg stadium. Dus de toekomstige scope is nog niet uitgewerkt, er zitten nog bugs in het framework die er uit moeten en de documentatie is kreupel. Maar met een beetje doorzetten wordt de wereld toch een beetje vrolijker met datajs. Ik vind het grootste voordeel dat de javascript code een stukje cleaner en leesbaarder is.

Want wat vind je van deze leesactie?

GET

OData.read(
  "http://localhost:2976/WcfDataService1.svc/Machines?
    $filter=SupervisorName eq  'user'",Success);

Dit is voldoende om een lijst van machines op te vragen, compleet met filter.
Dit filter is overigens de verdienste van OData.

Het opslaan van een
nieuw object kost bijna net zo weinig moeite:

POST

var requestPost =
  {method: "POST",
   requestUri: "htt p://localhost:2976/WcfDataService1.svc/Machines",
   data: {
     MachineName: 'Data',
     SupervisorName: 'user'
   }
  }

OData.request(requestPost, Success);

Hier versturen we een nieuw object om opgeslagen te laten
worden. En het verwijderen van een object is ook niet bepaald
spannend:

DELETE

var requestDelete =
  { method: "DELETE",
    requestUri: "htt p://localhost:2976/WcfDataService1.svc/Machines(31)"
  }

OData.request(requestDelete, Success); // geretourneerde data object is leeg

Natuurlijk moeten op de server wel de rechten op de tabel en in de service
opengezet zijn om respectivelijk een insert of delete te kunnen
uitvoeren.

Het wijzigen van een record in de database kan op twee
manieren:

1. Het te wijzigen object is al ooit in zijn geheel opgehaald in de browser.
Deze wordt in zijn geheel, maar gewijzigd, weer opgestuurd om opgeslagen te
worden. Dit is een PUT.

2. Als je van een object wel de structuur weet (naam en type van de
properties) en je weet ook de primary key en de waardes van de gewijzigde
kolommen, dan kan je een MERGE uitvoeren. De niet meegezonden, ongewijzigde (en wellicht onbekende) kolommen, blijven dan ongemoeid.

De eerste variant, de volledige update is heel eenvoudig. Je stuurt
gewoon het hele object op. Op moment van schrijven zit er een serialisatie bug
in DataServiceVersion 2.0 dus geef die niet mee. De documentatie op de site ten
spijt. Versie 1.0 werkt wel correct of laat deze weg.

PUT

var requestPut =
   {headers: { "DataServiceVersion": "1.0" },method: "PUT",
    requestUri: "htt p://localhost:2976/WcfDataService1.svc/Machines(33)",
    data: {
       MachineId: '33',
       SupervisorName: 'User',
       MachineName: 'Mixer'
           }
    }

OData.request(requestPut, Success);

Nogmaals de waarschuwing: als er nog meer, niet meegegeven, kolommen in het
record bestaan of als deze later toegevoegd worden aan de tabel, dan zal een PUT
die kolommen op NULL stellen…

Wil je dit voorkomen of als je het totale object niet compleet in een javascript object hebt zitten, dan kan je voor de tweede optie kunnen kiezen:

MERGE

var requestPut = {
    headers: { "DataServiceVersion": "1.0",
                "X-HTTP-Method": "MERGE"},
    method: "POST",
    requestUri: "htt p://localhost:2976/WcfDataService1.svc/Machines(33)",
    data: {
      MachineName: 'Mixer'
          }
   }

OData.request(requestPut, Success);

Helaas schijnt de MERGE niet integraal in internetland ondersteunt te worden
als HTTP verb. Daarom hebben de makers van datajs momenteel bovenstaande header entry bedacht. Ik heb vernomen dat ze nog nadenken over een meer high level notatie…

Met bovenstaande voorbeelden wordt een
aardige indruk gegeven van de verschillende calls die gemaakt kunnen worden. Ik verwijs toch nog even door naar de documentatie voor meer details zoals de batch opdrachten.

Nog een laatste tip, of eigenlijk vier… Ik liep in het begin tegen enkele vreemde
communicatieproblemen aan. En dan is het prettig om alle facetten van de
dataoverdracht goed te kunnen testen. Ik maak hierbij gebruik van de volgende
simpele hulpmiddelen:

  • 1. Plaats de javascript in aparte .JS bestanden die je als script verwijzing in je html pagina’s aanroept. Hiermee wordt het heel simpel om een breakpoint te zetten en te steppen in de javascript.
  • 2. Gebruik Fiddler of een gelijkwaardige tool om te zien wat er over de lijn gaat. Fiddler zal de eerste keer even duizelen met wat er te zien valt maar probeer daar even door heen te bijten. Volg gewoon request en response en negeer de rest. Het is voor mij onmisbaar geworden. Vergeet niet om voor lokaal debuggen het pac script aan te zetten in de opties.

Fiddler

  • 3. Zet op de server tijdens de testfase de “UseVerboseErrors” aan. Dit geeft voor de WCF Data Service eventuele fouten uit het entity framework of zelfs de database door.
public static void InitializeService(DataServiceConfiguration config)
{
  config.SetEntitySetAccessRule("*", EntitySetRights.All);
  config.SetEntitySetPageSize("*", 10);
  config.DataServiceBehavior.MaxProtocolVersion =
    DataServiceProtocolVersion.V2;
  config.UseVerboseErrors = true;
}
  • 4. Gebruik eventueel QueryInterceptors en ChangeInterceptors om de data bij binnenkomst op de WCF Data Service te bekijken, nog voordat het de context ingeschoten wordt.

Hiermee is javascript een volwaardige client voor OData geworden, en die
onbekende “niet .Net” client ondersteuning is één van de mooiste pijlers onder
OData.

Advertenties