69 lines
3.2 KiB
Markdown
69 lines
3.2 KiB
Markdown
# SAP Business One Service Layer Connector
|
||
|
||
Connector komunikuje výhradně přes SAP Business One Service Layer `/b1s/v1`.
|
||
|
||
Hlavní vlastnosti:
|
||
|
||
- login/logout přes Service Layer
|
||
- správa `B1SESSION` a `ROUTEID`
|
||
- automatický re-login po expiraci session
|
||
- HTTP API s credentials předávanými v `X-SAP-B1-*` hlavičkách podle AppFactory pravidel
|
||
- OData parametry `$select`, `$filter`, `$top`, `$skip`, `$orderby`
|
||
- stránkování přes `odata.nextLink` a `@odata.nextLink`
|
||
- retry pro dočasné chyby
|
||
- zod validace konfigurace a hlavních response tvarů
|
||
|
||
Bezpečnostní pravidla:
|
||
|
||
- při knihovním použití se konfigurace může číst z environment variables
|
||
- při HTTP API použití se SAP credentials posílají v request headers
|
||
- hesla, cookies a session tokeny se nelogují
|
||
- hesla a session tokeny se nevrací v běžných response
|
||
- testy nepoužívají reálný SAP přístup
|
||
- pro self-signed certifikáty je dostupné `rejectUnauthorized`, ale produkčně se doporučuje důvěryhodný certifikát
|
||
|
||
HTTP API hlavičky:
|
||
|
||
- `X-SAP-B1-BaseUrl`
|
||
- `X-SAP-B1-CompanyDB`
|
||
- `X-SAP-B1-Username`
|
||
- `X-SAP-B1-Password`
|
||
- `X-SAP-B1-Language` volitelně
|
||
- `X-SAP-B1-Reject-Unauthorized` volitelně
|
||
- `X-SAP-B1-Timeout-Ms` volitelně
|
||
|
||
## Detaily komunikace se Service Layer
|
||
|
||
- **Login** – `POST /b1s/v1/Login` s `{ CompanyDB, UserName, Password, Language? }`.
|
||
`Language` se posílá jako celé číslo (Service Layer očekává `Edm.Int32`); nenumerická
|
||
hodnota se vynechá. Z odpovědi se čtou cookies `B1SESSION` a `ROUTEID` (s fallbackem na
|
||
`SessionId` v body) a `SessionTimeout` (minuty) pro výpočet expirace.
|
||
- **Autentizované requesty** – posílají `Cookie: B1SESSION=…; ROUTEID=…`. Při `401`
|
||
connector jednou provede re-login a request zopakuje; re-login nesnižuje retry budget,
|
||
takže funguje i při `SAP_B1_RETRY_COUNT=0`.
|
||
- **Logout** – `POST /b1s/v1/Logout` se posílá **s aktivní session cookie**, jinak by
|
||
Service Layer nevěděl, kterou session ukončit, a nechal by ji běžet až do timeoutu.
|
||
- **Stránkování** – následuje `odata.nextLink` i `@odata.nextLink`. U absolutních
|
||
nextLinků se zachová i query string (`$skip` apod.), takže `listAll` nezacyklí.
|
||
|
||
## Reverse proxy a Swagger
|
||
|
||
Aplikace běží za AppFactory proxy na `/apps/<app-id>` (Caddy `handle_path` prefix před
|
||
předáním do containeru odstraní, takže container vidí routy bez prefixu a z requestu
|
||
veřejnou cestu nelze odvodit). Stejný přístup jako sousední služba `idoklad`:
|
||
|
||
- OpenAPI dokument se servíruje **pod stejným `/docs` prefixem** jako UI na
|
||
`GET /docs/openapi.json` (plus alias `GET /openapi.json` pro přímý přístup).
|
||
- Swagger UI načítá dokument přes **relativní** endpoint `openapi.json`, takže se
|
||
v prohlížeči vyhodnotí jako `{prefix}/docs/openapi.json` lokálně i za proxy, bez
|
||
hardcodování `/apps/<app-id>`.
|
||
- `servers[0].url` se nastaví z `ROOT_PATH` (fallback hlavička `X-Forwarded-Prefix`,
|
||
nakonec `/`), takže Swagger `Try it out` volá `…/apps/<app-id>/api/<resource>`.
|
||
|
||
| Kontrola | Lokálně (bez ROOT_PATH) | S `ROOT_PATH=/apps/sap-bo` |
|
||
|---|---|---|
|
||
| `GET /health` | 200 | 200 |
|
||
| `GET /docs` (Swagger UI) | 200 | 200 |
|
||
| `GET /docs/openapi.json` | 200 | 200 |
|
||
| `servers[0].url` v OpenAPI | `/` | `/apps/sap-bo` |
|