Zwei Türen in dasselbe B1.

Jedes Programm, das in SAP Business One etwas liest oder bucht, ohne dass ein Mensch es eintippt, nutzt eine von zwei Schnittstellen. Der Service Layer ist ein Webservice: Er läuft auf dem Server, spricht HTTPS und OData und antwortet mit JSON. Sie rufen ihn aus jeder Sprache auf, die eine Webanfrage senden kann, und der mobile Dienst von B1 hängt von ihm ab. Die DI API (Data Interface API) ist der ältere Weg: eine COM-Bibliothek (eine DLL) für Windows, geschrieben für C/C++, Visual Basic und .NET, die ein Programm auf dem Rechner lädt, auf dem es läuft.

Darunter sind beide gleich. SAPs eigener Service-Layer-Leitfaden beschreibt den DI Core im Service Layer als "the same one that is used by SAP Business One DI API", und die Geschäftslogik (Steuer, Buchung, Bestand) läuft in derselben Komponente wie im B1-Client. Deshalb durchläuft ein Auftrag, der durch eine der beiden Türen kommt, dieselben Prüfungen wie einer, der am Bildschirm erfasst wird: Lehnt B1 ihn im Fenster ab, lehnt es ihn auch aus Ihrem Programm ab. Auch die Namen von Objekten und Feldern sind weitgehend gleich: CardCode heißt in beiden CardCode.

Wann Sie welche nutzen.

  • Service Layer für alles Neue: eine Scanner-App, eine Webshop-Anbindung, eine Plantafel, eine Integration mit einem anderen System. Er läuft auf SUSE Linux und auf Windows, der Load Balancer lauscht meist auf Port 50000, und Ihr Programm braucht nichts neben B1 installiert. Er skaliert mit mehreren Knoten hinter dem Load Balancer.
  • DI API, wenn Sie ein bestehendes Add-on pflegen, das darauf aufbaut, oder wenn der Code ohnehin im B1-Client unter Windows läuft, neben der UI API. Die SDK-Hilfe von SAP weist darauf hin, dass die DI API kein Multithreading unterstützt, und sie muss auf jedem Rechner installiert sein, auf dem das Programm läuft.
  • Was nur die DI API kann: Der Leitfaden sagt es klar. Der Service Layer hat kein Recordset-Objekt für direktes SQL, keinen Import und Export nach XML und keine Transaktion über mehrere Anfragen: Es gibt kein StartTransaction und EndTransaction wie in der DI API. Jede Anfrage, auch ein Batch, ist eine eigene Transaktion.

In der DI API erzeugt ein Programm ein Company-Objekt, füllt Server, CompanyDB, UserName, Password und DbServerType und ruft Connect auf, das bei Erfolg 0 zurückgibt. Ein Auftrag ist dann GetBusinessObject(BoObjectTypes.oOrders), Zeile für Zeile gefüllt und mit Add gespeichert; schlägt ein Aufruf fehl, liefert GetLastError Code und Text. Der Rest dieses Leitfadens behandelt den Service Layer, denn dorthin geht neue Arbeit.

Anmelden, und wie lange eine Sitzung lebt.

Der Service Layer liegt unter https://<server>:50000/b1s/v2/. /b1s/v2 spricht OData Version 4, /b1s/v1 die ältere Version 3; nehmen Sie v2 für Neues. Ohne Anmeldung funktioniert nichts:

  • POST /b1s/v2/Login mit dem Body {"CompanyDB": "SBODEMOUS", "UserName": "manager", "Password": "1234"}. Ein optionales Language legt die Sprache der Meldungen fest.
  • Die Antwort ist 200 OK mit einer SessionId und einem SessionTimeout sowie zwei Cookies: B1SESSION und ROUTEID. Jede folgende Anfrage muss B1SESSION mitsenden; ROUTEID ist optional und hält Sie auf demselben Knoten hinter dem Load Balancer. Ein Browser sendet beide von selbst; ein Desktop- oder Serverprogramm muss sie setzen.
  • Die Sitzung endet nach einer Zeit ohne Anfragen: standardmäßig 30 Minuten, eingestellt als SessionTimeout in b1s.conf auf dem Server. Danach lautet die Antwort 401 Unauthorized mit Code 301, "Invalid session or session already timeout." Melden Sie sich neu an und wiederholen Sie die Anfrage.
  • POST /b1s/v2/Logout mit dem Cookie beendet die Sitzung; die Antwort ist 204 No Content. Melden Sie sich ab, wenn Sie fertig sind, und melden Sie sich nicht für jede einzelne Anfrage neu an: Die Anmeldung ist der schwerste Aufruf, den es gibt.

Daten lesen, anlegen und ändern.

Lesen ist ein GET auf eine Entität, mit OData-Abfrageoptionen, damit die Antwort klein bleibt. GET /b1s/v2/BusinessPartners?$select=CardCode,CardName&$filter=CardType eq 'cCustomer'&$top=5 liefert fünf Kunden mit nur Code und Name. $filter kennt eq, ne, gt, ge, lt, le, and, or, not und Funktionen wie startswith und contains; $orderby sortiert und $skip blättert. Einen Datensatz lesen Sie über seinen Schlüssel: GET /b1s/v2/BusinessPartners('C20000'), mit Anführungszeichen, weil der Schlüssel Text ist, und GET /b1s/v2/Orders(22) ohne, weil DocEntry eine Zahl ist. Die Zeilen eines Auftrags kommen mit dem Auftrag, in DocumentLines.

Eine Liste kommt nie auf einmal. Standardmäßig liefert der Service Layer 20 Datensätze pro Seite und fügt einen @odata.nextLink zur nächsten Seite hinzu; der Header Prefer: odata.maxpagesize=50 fordert größere Seiten an. Code, der nur die erste Seite liest und dann aufhört, ist der häufigste Fehler in einer ersten Integration.

Anlegen ist ein POST mit JSON. POST /b1s/v2/Orders mit {"CardCode": "C20000", "DocDueDate": "2026-11-15", "DocumentLines": [{"ItemCode": "A00001", "Quantity": 10}]} legt einen Kundenauftrag an und antwortet mit 201 Created und dem ganzen Beleg, einschließlich des neuen DocEntry und DocNum. Ändern ist ein PATCH auf den Schlüssel mit nur den Feldern, die sich ändern, zum Beispiel PATCH /b1s/v2/BusinessPartners('C20000') mit {"Phone1": "0201234567"}; die Antwort ist 204 No Content. Nutzen Sie PATCH, nicht PUT: PUT setzt jedes weggelassene Feld zurück. Schritte, die keine einfache Änderung sind, sind Aktionen, etwa POST /b1s/v2/Orders(22)/Close. Ein DELETE auf einen Auftrag wird abgelehnt, so wie Sie im B1-Client keinen löschen können.

Entitäten sind keine Tabellen.

Der Service Layer spricht in Geschäftsobjekten, die Datenbank in Tabellen. BusinessPartners liegt in OCRD; Orders ist der Kundenauftrag, mit dem Kopf in ORDR und den Zeilen in RDR1. Viele Marketingbelege teilen sich einen Entitätstyp, Document, daher haben Orders, Invoices und PurchaseOrders dieselben Felder. Die vollständige Liste der Entitäten, Felder und Aktionen steht in GET /b1s/v2/$metadata, einschließlich Ihrer eigenen benutzerdefinierten Felder; die Metadaten einer Firmendatenbank können also von denen einer anderen abweichen. Ein Haken: Ein neues benutzerdefiniertes Feld oder eine neue Tabelle ist erst nach einem Neustart des Service Layer sichtbar.

Eine Tabelle mit SQL zu lesen ist in Ordnung. Hineinzuschreiben nicht. SAPs SDK-Regeln erlauben keine Änderungen an Standardobjekten, und ein INSERT oder UPDATE direkt in ORDR überspringt alles, was B1 beim Hinzufügen eines Belegs tut: Nummerierung, Bestand, die Journalbuchung, Berechtigungen, Genehmigung, das Änderungsprotokoll. Sie haben dann Daten, die B1 nie geprüft hat. Alles, was Daten ändert, läuft über den Service Layer oder die DI API, ohne Ausnahme.

Fehler, Batches und gespeicherte Abfragen.

  • Fehler kommen als HTTP-Status zurück (zum Beispiel 400 für eine abgelehnte Anfrage, 401 ohne gültige Sitzung, 403 ohne Berechtigung) und als JSON-Body mit einem error-Objekt mit code und message: derselbe Text, den ein Benutzer im B1-Client sähe, etwa ein Geschäftspartnercode, der schon vergeben ist. Protokollieren Sie diesen Text; er sagt fast immer, was falsch ist.
  • Batch-Anfragen gehen als eine Multipart-Nachricht an POST /b1s/v2/$batch. Anfragen innerhalb eines Change Sets gelingen nur gemeinsam: Schlägt eine fehl, wird das ganze Change Set zurückgerollt. Das ist die Antwort des Service Layer auf eine Transaktion über mehrere Belege, solange sie in einen Batch passen.
  • Gespeicherte SQL-Abfragen (seit 10.0 FP 2011): Sie speichern ein SELECT als Eintrag in SQLQueries, mit SqlCode, SqlName und SqlText, und führen es mit GET /b1s/v2/SQLQueries('sql01')/List aus. Nur Lesen ist erlaubt; UPDATE, INSERT und DELETE werden abgelehnt, und nur freigegebene Tabellen und Spalten sind abfragbar. Ein normaler Benutzer braucht pro Abfrage eine Berechtigung unter General Authorizations. Die Details stehen in unserem Leitfaden zu SQL-Abfragen.

Bevor Sie anfangen: eine Checkliste.

  • Der Service Layer ist installiert und läuft auf Ihrem B1-Server, und Ihr Programm erreicht Port 50000 über HTTPS. Er ist für interne Aufrufe gedacht; er muss nicht ins Internet.
  • Eine Testfirma, an der Sie Anfragen ausprobieren, nie die Produktivdatenbank.
  • Ein eigener B1-Benutzer für das Programm, mit nur den Berechtigungen, die es braucht, und eine Lizenz für diesen Benutzer. Indirect Access ist der Typ für Programme; siehe unseren Leitfaden zu B1-Lizenzen, und stimmen Sie es mit Ihrem Partner ab.
  • Eine Sitzung, die über Anfragen hinweg wiederverwendet wird, eine neue Anmeldung bei 401 und eine Abmeldung am Ende.
  • Paging berücksichtigt: Folgen Sie @odata.nextLink, bis er verschwindet.
  • Feldnamen aus den $metadata Ihrer eigenen Firmendatenbank, nicht geraten und nicht aus einem anderen System übernommen.
  • Der Fehlertext jeder abgelehnten Anfrage in einem Protokoll, und nichts direkt in SAP-Tabellen geschrieben.

Wie KoonLearn es angeht.

KoonLearn, unsere Trainingssimulation für SAP Business One, hat ein Vertiefungsmodul Service Layer und DI API: Abschnitte zu Architektur und Anmeldung, Lesen, Schreiben, Fortgeschritten, DI API, Fehlersuche. Sie arbeiten in einer Request-Konsole im Browser: Methode, URL, Header und Body, eine Schaltfläche Send und eine Antwort mit Status und JSON aus den Daten der Trainingsfirma. Sie melden sich an und sehen Ihre Sitzung ablaufen, filtern und blättern durch Geschäftspartner und Bestellungen, legen Belege per POST an und ändern sie per PATCH, führen Close und Cancel aus, senden ein Change Set in einem Batch und reparieren Anfragen, die mit 400, 401 oder 404 zurückkommen. Der DI-API-Teil ist Code lesen und den Fehler finden: eine Verbindung, die nicht geprüft wird, eine Transaktion ohne Fehlerbehandlung, eine Schleife über ein Recordset. Die Konsole antwortet wie der Service Layer; sie ist keiner, und nichts wird installiert oder mit einem echten B1 verbunden.

Preise und Optionen finden Sie im Kundenportal. Das Modul endet mit einem Quiz und einer Modulprüfung. Es geht über die Prüfung hinaus: Es ist keine Vorbereitung auf C_TB120 und vergibt kein Zertifikat. Wenn Sie zuerst sehen möchten, wie KoonLearn funktioniert: Kapitel 03 Einkauf ist ohne Konto kostenlos, starten Sie das kostenlose Kapitel auf learn.koonsystems.com. KoonLearn ist nicht mit der SAP SE verbunden.

Quellen: SAP, Working with SAP Business One Service Layer (Version 1.29, 27-07-2026: Anmeldung und Sitzung, CRUD, Abfrageoptionen, Paging, Batch, SQL Query, Einschränkungen gegenüber der DI API); die Service-Layer-API-Referenz (Login, Logout, BusinessPartners, Orders); SAP Business One SDK Help 10.0 (DI API, Verbinden, Fehlerbehandlung, Änderungen am Standard); DI-API-Referenz 10.0 (Company, Documents); Database Tables Reference 10.0 (OCRD, ORDR, RDR1); die Modulübersicht von KoonLearn. SAP und SAP Business One sind Marken der SAP SE.