API Anleitung

Zugriff über HTTP mit XML / JSON

Die LogMyTime API ist als OData-API für den einfachen und schnell zu implementierenden Zugriff mit Bibliotheken optimiert. Können Sie aus technischen Gründen keine der angeführten Bibliotheken verwenden, ist als Alternative auch der direkte Zugriff auf die API per HTTP und XML oder JSONP möglich. Unsere API ist als RESTful Web Service angelegt, so dass auch dies recht leicht fallen sollte.

Jede Ressource (z.B. Zeiteintrag, Kunde, Projekt...) ist dabei als eigene URI zugänglich. Die Ressourcen liegen jeweils eine Verzeichnisebene unter der Root-URI der API:

http(s)://api.logmytime.de/v1/api.svc/{RessourceTyp}

Es gibt folgende Ressourcetypen:

RessourcenTyp URI Anmerkungen
Projekte {root}/Projects weitere Informationen
Kunden {root}/Clients weitere Informationen
Tätigkeiten {root}/Tasks weitere Informationen
Zeiteinträge {root}/TimeEntries weitere Informationen
Mitarbeiter {root}/Users Accountdaten der Mitarbeiter einer Firma
weitere Informationen
Kontoeinstellungen {root}/AccountSettings Eine Teilmenge der Stammdaten der Firma, die allen Benutzern zugänglich ist
weitere Informationen
Stoppuhr abhängig von der jeweiligen Operation Funktionen zum Starten, Stoppen und Abfragen der Stoppuhr

Jede Ressource hat eine eindeutige ID, über die sie in der jeweiligen Ressourcenkategorie adressiert werden kann.

Beispiel: Das Projekt mit der ID 1234 ist unter folgenden URI verfügbar:

http://api.logmytime.de/V1/Projects(1234)

Die auf diesen Ressourcen auszuübenden Operationen werden durch die HTTP Verben bestimmt:

  • GET zum Lesen von Ressourcen
  • POST zum Erstellen neuer Ressourcen
  • MERGE zum Bearbeiten von Ressourcen
  • DELETE zum Löschen von Ressourcen

Debugging-Tools

Falls Sie die API über HTTP(S) ansprechen, sind die von uns aufgelisteten Tools für erste Tests sowie für späteres Debugging sehr nützlich.

Ein- und Ausgabeformate

Die LogMyTime API beherrscht das Lesen und Schreiben von Ressourcen im XML- und im JSON-Format. Geben Sie kein Format explizit an, wird von der API das XML-Format als Defaultwert angenommen.

Die Ein- und Ausgabe-Formate können im HTTP Request Header angegeben werden.

Im Request Header:
accept: application/atom+xml
bzw.
accept: application/json

Xml-Format

Tipp: Da das Atom-Format auch von RSS-Feeds benutzt wird, können Ressourcenlisten auch als Webfeed zugänglich gemacht werden. Sie können z.B. ganz einfach einen Newsfeed mit den neusten Zeiteinträgen abonnieren.

Die XML-Ausgabe der LogMyTime API erfolgt im XML-Atom Format.

Die eigentlichen XML-Rohdaten für eine Ressource sind in den content-Elementen enthalten. Für jede Eigenschaft wird zusätzlich zum Wert auch der Datentyp der Eigenschaft als type-Attribut angegeben.


Beispiel: Ein Projektliste wird beim Lesezugriff wie folgt von der API ausgegeben:

Request Header:
GET /V1/Api.svc/Projects
X-LogMyTimeApiKey: {apikey}
Host: api.logmytime.de
accept: application/atom+xml
Response Header:
HTTP/1.1 200 OK
Content-Length: 10085
Content-Type: application/atom+xml;charset=utf-8
Response Content:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<feed ...>
   ...
   <!--Der Eintrag für das erste Projekt:-->
     <entry>
        ...
        <!--Typ der Ressource (ein Projekt)-->
        <category term="LogMyTime.Project" .../>
        <!--Eigenschaften es ersten Projektes:-->
        <content type="application/xml">
          <m:properties>
            <d:ID m:type="Edm.Int32">4781</d:ID>
            <d:Name>Zeiterfassung</d:Name>
            <d:Active m:type="Edm.Boolean">true</d:Active>
            <d:Comment m:null="true" />
            <d:TimeBudget m:type="Edm.Int32">122400</d:TimeBudget>
            <d:ClientID m:type="Edm.Int32">1004</d:ClientID>
            <d:LastChangeAuthor m:type="Edm.Int32">58934</d:LastChangeAuthor>
            <d:LastChangeTime m:type="Edm.DateTime">
               2010-07-20T17:11:11.063
            </d:LastChangeTime>
          </m:properties>
        </content>
     </entry>
     ...weitere Projekte...
</feed>

JSON-Format

Das JSON-Format bietet eine leichtgewichtigere Alternative zu XML. Es wird meist in Javascript-Code verwendet, allerdings gibt es auch JSON-Parser für viele weitere Programmiersprachen.

Das JSON-Format kann mit dem HTTP-Header "accept: application/json" angefordert werden.

Beispiel: Ein Projektliste wird beim Lesezugriff als Javascript wie folgt von der API ausgegeben:

Request Header:
GET /V1/Api.svc/Projects
Accept: application/json
X-LogMyTimeApiKey: {apikey}
Host: api.logmytime.de
Response Header:
HTTP/1.1 200 OK
Content-Length: 10085
Content-Type: application/json;charset=utf-8
Response Content:
{
 //Metadaten des ersten Projektes:
 "d": {
  "__metadata": {
    "uri": "https://api.logmytime.de/V1/API.svc/Projects(4781)",
    "type": "LogMyTime.Project"
  },
  //Projekteigenschaften:
  "ID": 4781,
  "Name": "Mondlangung",
  "Active": true,
  "Comment": null,
  "TimeBudget": 122400,
  "ClientID": 1004,
  "LastChangeAuthor": 58934,
  "LastChangeTime": "\/Date(1279645871063)\/",
  //Referenzen des Projektes auf andere Ressourcen:
  "Client": {
    "__deferred": {
      "uri": "https://api.logmytime.de/V1/API.svc/Projects(4781)/Client"
    }
  },
  "TimeEntries": {
    "__deferred": {
      "uri": "https://api.logmytime.de/V1/API.svc/Projects(4781)/TimeEntries"
    }
  }
 }
 //weitere Projekte...
}

Lesezugriff

Im Abschnitt über Ein- und Ausgabeformate sind ein paar Beispiele zu Lesezugriffen, Authentifizierung und die daraus resultierenden Ausgaben zu sehen.

Ressourcen können einzeln oder als Liste von bis zu 100 Ressourcen pro Seite ausgeben werden. Einzelne Ressourcen werden über ihre Unique ID angesprochen. Auch eine Ausgabe einzelner Eigenschaften ist möglich.

Beispiele:

Bis zu 100 Projekte in Ihrem Firmenaccount einlesen:

GET /V1/Api.svc/Projects

Das Projekt mit der ID 4913 einlesen:

GET /V1/Api.svc/Projects(4913)

Beispielausgaben hierzu sehen Sie in dem Abschnitt über Ausgabeformate.

Erfolgreiche Lesezugriffe werden vom Server mit dem HTTP Code "200 OK" sowie der angeforderten Ressource beantwortet. Existiert eine Ressource nicht oder ist sie mit dem gegebenen API-Schlüssel nicht zugänglich, antwortet der Server stattdessen mit "404 Not Found".

Paging bei Lesezugriffen

Wenn eine angeforderte Ressourcenliste länger als 100 Einheiten ist, liefert der Server nur die ersten 100 Einheiten sowie einen Link zum Anfordern der nächsten 100 Einheiten zurück.

Beispiel: Die API gibt bei Verwendung des XML-Formats und Anfordern einer Liste von mehr als 100 Projekten den Link zu den nächsten Projekten wie folgt aus:

...
<link rel="next"
href="https://api.logmytime.de/V1/Api.svc/Projects?$skiptoken='{ID_DER_NÄCHSTEN_RESSOURCE}'" />
...

Es kann wahlweise auch mit dem GET-Parameter $top={Seitengröße} eine kleinere Seitengröße gewählt werden.

Beispiel: Nur die ersten 20 Projekte ausgeben:

GET /V1/Api.svc/Projects?$top=20

Komplexe Lesezugriffe

Da die API dem OData-Standard für RESTful Web Services folgt, können auch komplexere Suchanfragen ähnlich wie bei der Datenbanksprache SQL serverseitig ausgeführt werden.

Beispiel: alle Zeiteinträge für das Projekt 4914 nach Startdatum sortiert:

GET /v1/api.svc/TimeEntries?$filter=ProjectID eq 4941&$orderby=StartTime

Das "eq" steht dabei für "equals", also "gleich".

Beispiel: alle Zeiteinträge nach dem 27.5.2015, die die Tätigkeits-ID 1212 haben:

GET /v1/api.svc/TimeEntries?$filter=LastChangeTime%20gt%20datetime'2015-05-27' and TaskID eq 1212&$orderby=StartTime

Das "eq" steht dabei für "equals", also "gleich".

https://api.logmytime.de/v1/api.svc/TimeEntries?$filter=LastChangeTime%20gt%20datetime%272015-05-27%27

Alle Ressourcen (ausser AccountSettings) sind untereinender verlinkt. Diese Links können ebenfalls für komplexe Lesezugriffe benutzt werden. Die vorherige Abfrage hätte man z.B. genauso gut folgendermaßen schreiben können:

GET /v1/api.svc/Projects(4914)/TimeEntries?$orderby=StartTime

Dies ist nur ein Ausschnitt der möglichen Lesezugriffe. Möglich sind z.B. auch Projektion und Expansion (entpricht grob JOIN-operationen in SQL).

Genaue Details sowie zahlreiche Beispiele zu komplexen Lesezugriffen sind in dem entsprechenden Kapitel der offiziellen OData-Dokumentation zu finden.

Schreibzugriff

Schreibzugriffe erfolgen auf den gleichen URIs wie auch simple Lesezugriffe. Die verschiedenen Arten von Schreibzugriffen werden durch das HTTP Verb spezifiziert.

Im Gegensatz zum Lesezugriff müssen Sie auch den Content-Type (application/atom+xml oder application/json) in den HTTP Headern angeben.

Schreibzugriff - Erstellen von Ressourcen

Das Ändern von Ressourcen erfolgt mit dem HTTP-Verb POST. Optionale Eigenschaften der Ressource können Sie einfach auslassen, diese werden dann mit Defaultwerten belegt.

Achtung: Geben Sie beim Erstellen einer Ressource keine Ressourcen-ID an. Die API lehnt solche Anfragen ab, da die ID serverseitig vergeben wird.

Ebenfalls auslassen können Sie Metadaten, die nur für XML-Feeds relevant wären. Zwingend notwendig sind nur die <entry>, <content> und <properties>-Elemente sowie die dazugehöregen XML-Namespaces.

Ein erfolgreicher Erstellungsvorgang wird vom Server mit dem Status-Code "201 Created" sowie der neu erstellten Ressource beantwortet. Aus der Antwort können Sie auch die an die Ressource vergebene Ressuorcen-ID auslesen.

Beispiel: Ein neues aktives Projekt mit dem Namen "Mondlandung" erstellen:

Request Header:
POST /V1/Api.svc/Projects
Content-Type: application/atom+xml
X-LogMyTimeApiKey: {apischluessel}
Content-Length: 377
Host: api.logmytime.de
Request Content:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<entry xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
xmlns="http://www.w3.org/2005/Atom">
   <content type="application/xml">
    <m:properties>
      <d:Name>Mondlandung</d:Name>
      <d:Active>true</d:Active>
    </m:properties>
  </content>
</entry>
Response Header:
HTTP/1.1 201 Created
Content-Length: 1830
Content-Type: application/atom+xml;charset=utf-8
Location: https://api.logmytime.de/V1/API.svc/Projects(4940)
Response Content:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<entry ...>
<!--XML Feed Metadaten...-->
<!--Das neu erstellte Projekt: -->
	<content type="application/xml">
		<m:properties>
			<d:ID m:type="Edm.Int32">8164</d:ID>
			<d:Name>Zeiterfassung</d:Name>
			<d:Active m:type="Edm.Boolean">false</d:Active>
			<d:Comment m:null="true" />
			<d:TimeBudget m:type="Edm.Int32" m:null="true" />
			<d:ClientID m:type="Edm.Int32" m:null="true" />
			<d:LastChangeAuthor m:type="Edm.Int32">58934</d:LastChangeAuthor>
			<d:LastChangeTime m:type="Edm.DateTime">
			  2010-08-03T16:55:05.8516991+02:00
			</d:LastChangeTime>
		</m:properties>
	</content>
</entry>

Schreibzugriff - Ändern von Ressourcen

Das Ändern von Ressourcen erfolgt mit dem HTTP-Verb MERGE. Als Adresse muss eine bestimmte Ressource (anstatt der gesamten Liste eines Ressourcentyps) in der URI angegeben werden.

Ein erfolgreicher Änderungsvorgang wird vom Server mit dem Status-Code "HTTP/1.1 204 No Content" beantwortet. Es gibt hierbei keinen Request Content.

Beispiel: Das Projekt mit der ID 8164 in "Mondlandung" umbenennen:

Request Header:
MERGE /V1/Api.svc/Projects(8164)
X-LogMyTimeApiKey: {apischluessel}
Content-Type: application/atom+xml
Content-Length: 383
Request Content:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<entry xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
xmlns="http://www.w3.org/2005/Atom">
   <content type="application/xml">
    <m:properties>
      <d:Name>Mondlandung</d:Name>
    </m:properties>
  </content>
</entry>
Response Header:
HTTP/1.1 204 No Content

Achtung: Der OData Standard sieht zwar für Updates nicht nur MERGE, sondern auch PUT als HTTP-Verb vor, jedoch werden dabei alle nicht explizit spezifizierten Eigenschaften auf ihre Defaultwerte zurückgesetzt. Im obigen Beispiel würde z.B. das Projekt nicht nur umbenannt, sondern auch deaktiviert, da für die Eigenschaft "Active" kein Wert angegeben wird. Wir raten daher von PUT ab, verwenden Sie für Updates am besten nur MERGE.

Schreibzugriff - Löschen von Ressourcen

Das Löschen von Ressourcen erfolgt mit dem HTTP-Verb DELETE. Wie auch beim Ändern von Ressourcen, muss eine bestimmte Ressource (anstatt der gesamten Liste eines Ressourcentyps) in der URI angegeben werden.

Ein erfolgreicher Löschvorgang wird vom Server mit dem Status-Code "HTTP/1.1 204 No Content" beantwortet. Es gibt hierbei keinen Request Content.

Request Header:
DELETE /V1/Api.svc/Projects(8482)
X-LogMytimeAPIKey: {apischluessel}
Response Header:
HTTP/1.1 204 No Content

Fehlerhafte Zugriffe

Bei Fehlern gibt die API einen HTTP Fehlercode im 400er oder 500er Bereich aus. Die Antwort enthält auch eine genauere Beschreibung des Fehlers.

Beispiel: Fehlerhafter Versuch, ein neues Projekt ohne Namen zu erstellen:

Request Header:
POST /V1/Api.svc/Projects
X-LogMytimeAPIKey: {apikey}
Content-Type: application/atom+xml
Content-Length: 381
Request Content:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<entry xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
xmlns="http://www.w3.org/2005/Atom">
	<content type="application/xml">
		<m:properties>
			<d:Active>true</d:Active>
		</m:properties>
	</content>
</entry>
Response Header:
HTTP/1.1 409 Conflict
Content-Length: 279
Content-Type: application/xml
Response Content:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
   <code></code>
   <message xml:lang="de-DE">
        Validierung der Project Ressource fehlgeschlagen: Projektname fehlt
   </message>
</error>

Weitergehende Informationen

Diese Einführung in OData sollte Sie in die Lage versetzen, einfache Operationen mit der API auszuführen.

Es gibt im WWW viele Informationen und Beispiele zu OData. Wir empfehlen vor allem die offizielle odata webseite, die sowohl eine ausführliche Dokumentation als auch zahlreiche links zu tutorials zum Anbinden von OData-Apis beinhaltet:

Bei konkreten Fragen helfen wir Ihnen natürlich auch gerne weiter .