Der einfachste Weg auf die LogMyTime API zuzugreifen, liegt für Softwarentwickler in der Verwendung einer Bibliothek. Diese abstrahiert Lese- und Schreibzugriffe über HTTP and die API. Dadurch entfällt das manuelle Absenden von HTTP Requests und das Parsen der Serverantworten. Stattdessen verwenden Sie eine komfortable Schnittstelle für Ihre bevorzugte Programmiersprache:
Eine Auflistung aller Bibliotheken mit Download-Links und Dokumentationen finden Sie auf der OData-Webseite.
Als Beispiel für die einfachhe Handhabung betrachten wir den Zugriff mit C# auf die API mittels der .NET 3.5 Bibliothek.
Um auf die API zuzugreifen, muss man zunächst eine Service-Referenz erstellen. Dies wird von Visual Studio durch ein paar Mausklicks und der Angabe der URI der LogMyTime API automatisch generiert.
Nun kann eine Instanz einer solchen Api-Referenz erschaffen werden:
var dataSource = new APIDataSource(new Uri("http://api.logmytime.de/V1/Api.svc"));
Für die Authentifizierung per HTTP Header weisen wir die Api-Referenz an, bei jedem Request eine Funktion namens AttachAuthHeader aufzurufen:
dataSource.SendingRequest += AttachAuthHeader;
Die Funktion fügt zur Athentifizierung den API-Schlüssel des Mitarbeiters als HTTP Header an:
private static void AttachAuthHeader(object sender, SendingRequestEventArgs e)
{
e.RequestHeaders.Add(new NameValueCollection{{"X-LogMyTimeApiKey", DER_APISCHLUESSEL}});
}
Nun können wir mit dem eigentlichen Zugriff auf die API beginnen. Die Service-Referenz besitzt für jeden Ressourcentyp der LogMyTime API ein IQueryable-Objekt, aus dem diese Ressourcen ausgelesen werden können.
Nehmen wir an, auf dem Server wären 2 aktive Projekte namens 'Mondlandung' und 'Marsexpedition', sowie ein abgelegtes Projekt namens 'Kühlschrank abtauen'.
Beispiel: Um die Namen aller Projekte und deren Status aufzulisten:
foreach (var project in dataSource.Projects)
{
Console.WriteLine(project.Name+": "+project.Active?"Aktiv":"Abgelegt");
}
Ausgabe:
Mondlandung: Aktiv Marsexpedition: Aktiv Kühlschrank abtauen: Abgelegt
Es können auch serverseitige SQL-ahnliche Befehle (sogenannte Query String Options) beim Lesezugriff ausgeführt werden.
Beispiel: Anstatt aller Projekte sollen nur die aktiven Projekte vom LogMyTime-Server geladen werden. Die Projekte sollen auch gleich serverseitig alphabetisch sortieren werden. Dazu muss man das vorherige Beispiel wie folgt abändern:
foreach (var project in dataSource.Projects
.AddQueryOption("$filter", "Active")
.AddQueryOption("$orderby", "Name")
)
{
Console.WriteLine(project.Name);
}
Ausgabe:
Marsexpedition: Aktiv Mondlandung: Aktiv
Eine Dokumentation aller Query String Options finden Sie auf der OData-Webseite.
Die Service-Referenz unterstützt sogar Links der Ressourcen untereinander. Diese werden durch Eigenschaften in den Ressourcen-Stubs der Service-Referenz repräsentiert.
Beispielsweise sind bei LogMyTime der Projektname und die Tätigkeit keine unmittelbaren Eigenschaften einer Zeiteintrags-Ressource. Mit der Bibliothek kann man auf Projektname und Tätigkeit aber so zugreifen, als ob dies der Fall wäre. Man muss nur die Service-Referenz anweisen, die entsprechenden Child-Referenzen Project und Task beim Ladevorgang zu expandieren, also in dem gleichen Request mit zu laden.
Beispiel: Alle Zeiteinträge mit Projekt und Tätigkeit auflisten:
foreach (var timeEntry in dataSource.TimeEntries
.Expand("Project")
.Expand("Task"))
{
Console.WriteLine("Von {0} bis {1}: {2} / {3}",
timeEntry.StartTime,
timeEntry.EndTime,
timeEntry.Project.Name,
timeEntry.Task!=null?timeEntry.Task.Description:null);
}
Ausgabe:
Von 27.07.2010 15:34:23 bis 27.07.2010 17:48:26: Marsexpedition / Recherche Von 27.07.2010 12:31:30 bis 27.07.2010 14:06:31: Marsexpedition / Meeting Von 27.07.2010 01:00:00 bis 27.07.2010 04:00:00: Mondlandung / Triebwerk B montieren ...
Der Schreibzugriff gestaltet sich ähnlich einfach. Für das Erstellen neuer Ressourcen muss der Ressourcen-Stub mit der AddTo{RessourceListenName}-Methode in die Service-Referenz eingefügt werden. Anschließend weist man die Service-Referenz an, die neue Ressource zum Server zu übertragen.
Beispiel: Ein neues aktives Projekt namens "Mondlandung" anlegen und dessen serverseitige ID ausgeben
Project newProject = new Project
{
Name = "Mondlandung",
Active = true
};
//Das neue Projekt in die API Servicereferenz einfügen
dataSource.AddToProjects(newProject);
//Änderungen an Server absenden
SubmitChanges(dataSource);
//Das Stub erhält automatisch die serverseitige ID des neuen Projektes:
Console.WriteLine("Das Projekt wurde angelegt. Die Projekt-ID lautet: "+newProject.ID);
Beim Ändern von Ressourcen muss man der Service-Referenz explizit mitteilen, dass die am Referenz-Stub gemachten Änderungen mit dem Server synchronisiert werden sollen.
Beispiel: Das Projekt namens "Mondlandung" in "Mondlandungsexpedition" umbenennen:
//Projekt laden...
var enumerator = dataSource.Projects
.AddQueryOption("$filter", "Name eq 'Mondlandung'")
.GetEnumerator();
enumerator.MoveNext();
Project project =enumerator.Current;
//umbenennen...
newProject.Name = "Mondlandungsexpedition";
//den Stub zum Synchronisieren auf den Server freigeben...
dataSource.UpdateObject(newProject);
//und zum Server übertragen
SubmitChanges(dataSource);
Das Löschen ist ist ähnlich einfach wie das Erstellen von Ressourcen.
Beispiel: Das Projekt Namens "Mondlandung" löschen:
//Projekt vom Server laden...
var enumerator = dataSource.Projects
.AddQueryOption("$filter", "Name eq 'Mondlandung'")
.GetEnumerator();
enumerator.MoveNext();
Project project =enumerator.Current;
//Service-Referenz anweisen, die Ressource beim nächsten Synchronisieren zu löschen
dataSource.DeleteObject(project);
//Änderungen an den Server übertragen
SubmitChanges(dataSource);
In den Bibliotheken ist keine clientseitige Validierung für die jeweiligen Ressourcen enthalten, z.B. wird clientseitig nicht geprüft, ob Sie beim Erstellen eines neuen Projektes einen Projektnamen angegeben haben.
OData-Bibliotheken für streng typisierte Programmiersprachen (z.B. die .NET Bibliothek) erstellen schon zur Designzeit Referenzen auf die API, die dann als Teil des Programms kompiliert werden.
Im Fall von .NET reagiert eine solche Service-Referenz standardmäßig mit Laufzeitfehlern auf nachträglich zur API hinzugefügte Ressourceneigenschaften, auch wenn diese eigentlich vom Server mit Defaultwerten belegt werden können. Im Fall von .NET kann man dieses Verhalten mittels der Eigenschaft IgnoreMissingProperties abschalten. Dies sollten Sie tun, um Ihren Client so zukunftssicher wie möglich zu implementieren.
Möglicherweise müssen Sie dies bei anderen Bibliotheken für streng typisierte Sprachen (z.B. Java, Ruby) ebenfalls beachten.

LogMyTime Zeiterfassung
Am Rasen 31
36041 Fulda
Tel. 0661-86977477