REST API voor ontwikkelaars
Dit onderwerp is een overzicht van alle ins & outs van de REST API.
Er is een aparte REST-help met veel informatie per endpoint en de mogelijkheid om endpoints te testen. Ga nu naar docs.afas.help.
Inhoud |
Algemeen
AFAS biedt standaard in Profit voor alle klanten een API om data uit te wisselen. Deze API is reactief, heeft dynamische endpoints voor het ophalen van data en vaste endpoints voor het ontvangen van data. In deze beschrijving staat lees je hoe je de API aanroept en welke mogelijkheden en beperkingen er zijn.
Let op:
Je vindt alle endpoints voor connectoren op de centrale pagina URL's van REST Services.
Vereisten
Om de API aan te roepen heb je een omgevingsID en een token nodig. De beheerder van de AFAS omgeving waarmee je de verbinding legt kan je deze informatie geven.
Protocols
De API van AFAS Software is benaderbaar via zowel REST(JSON) als SOAP(XML).
Voor alle requests is TLS 1.2 verplicht.
Tools
AFAS heeft een eigen test-platform voor het ontwikkelen en testen van requests, namelijk AFAS Connect. AFAS Connect is beschikbaar voor iedereen die een account aanmaakt. Deze account is niet gekoppeld aan andere AFAS-accounts.
Aanroep
Voor een aanroep heb je nodig:
- Token
- OmgevingsID
- Omgevingstype
Let op:
De totale omvang van een API-call is maximaal 75 MB.
Endpoints
De basis van de endpoint bestaan uit de volgende elementen:
https://OmgevingsID.webservicetypeOmgevingstype.online
Omgeving |
Voorbeeld |
Productie |
https://12345.rest.afas.online/profitrestservices |
Test |
https://12345.resttest.afas.online/profitrestservices |
Accept |
https://12345.restaccept.afas.online/profitrestservices |
Let op:
Je vindt alle endpoints voor connectoren op de centrale pagina URL's van REST Services.
Header
De header wordt alleen gebruikt voor de autorisatie.
Key: "Authorization"
Value: "AfasToken PHRva2VuPjx2ZXJzaW9uPjE8L3ZlcnNpb24+PGRhdGE+NTQ3NDAwOTM4MzI0OTYwODE4NDU0Nz
RhYmNkZWZnaGlqa2xtbm9wcTc0MDA5MzgzMjQ5NjA4MTg0MTIzNDEyNzwvZGF0YT48L3Rva2VuPg=="
De value is de Base64-string van het token inclusief xml-tags. Hiervoor staat AfasToken + spatie.
Voorbeeld: token-conversie
Token:
<token><version>1</version><data>54740093832496081845474abcdefghijklmnopq740093832496081841234127</data></token>
Base64 string:
PHRva2VuPjx2ZXJzaW9uPjE8L3ZlcnNpb24+PGRhdGE+NTQ3NDAwOTM4MzI0OTYwODE4N
DU0NzRhYmNkZWZnaGlqa2xtbm9wcTc0MDA5MzgzMjQ5NjA4MTg0MTIzNDEyNzwvZGF0YT48L3Rva2VuPg==
Taalkeuze meegeven in de header
In de header kun je ook een taalkeuze meegeven. Als je dit niet meegeeft, is de taal Nederlands.
Key: Accept-Language
Value: de gewenste taalcode. Als een taal niet herkend wordt, is nl-nl de default. Geaccepteerde talen zijn:
- nl-nl (Nederlands)
- nl-be (Vlaams)
- fr-fr (Frans)
- de-de (Duits)
- en-us (Engels)
Bij een GetConnector doet deze header niet zo veel. De codetabelwaarden (voor bijv. geslacht) komen altijd in het Nederlands terug. Als je de meta-info ophaalt, is die wel vertaald; zoals de columnHeader.
Bij een UpdateConnector bepaalt deze header de taal waarin de codetabelwaarden moeten worden meegegeven. Dus wil je het geslacht van een persoon aanpassen naar Man, dan moet je bij nl-nl "M" van Man meegeven, bij fr-fr is dat "H" van Homme.
Metainfo request
De metainformatie-request geeft informatie over de omgeving, de beschikbare GetConnectoren en de beschikbare UpdateConnectoren.
URL van de request: https://12345.rest.afas.online/ProfitRestServices/metainfo
Header: "Authorization: AfasToken PHRva2VuPjx2ZXJzaW9uPjE8L3ZlcnNpb24+PGRhdGE+NTQ3NDAwOTM4MzI0O
TYwODE4NDU0NzRhYmNkZWZnaGlqa2xtbm9wcTc0MDA5MzgzMjQ5NjA4MTg0MTIzNDEyNzwvZGF0YT48L3Rva2VuPg=="
OTP
AFAS biedt de mogelijkheid om een One Time Password (OTP) te gebruiken in plaats van een token. Dit is handig in situaties waarin gebruikers zichzelf moeten registeren in een applicatie.
Zie verder:
GetConnector - REST
Een externe applicatie kan met een GetConnector records ophalen uit de Profit-database. Hiervoor zijn dynamische endpoints waarmee je zelf geconfigureerde dataset kan opvragen. Een AFAS-beheerder kan deze GetConnector-definities zelf samenstellen.
Je kunt alleen GetConnectoren aanroepen die in de app connector geactiveerd zijn.
Voorbeeld resultaat:
{
"skip": 0,
"take": 1,
"rows": [
{
"BcCo": "1000001",
"Type": "Organisatie",
"SearchName": "AFAS Software B.V."
}
]
}
Filtering
Een GetConnector-definitie kan een ingebouwd filter bevatten, bijvoorbeeld het huidige jaar. Daarnaast kun je per request een filter toepassen. Voor het samenstellen van het filter kun je het best gebruik maken van de tools die beschikbaar zijn op connect.afas.nl.
De volgende filter-operators zijn beschikbaar:
Type |
beschrijving |
Operator |
= |
is gelijk aan |
1 |
>= |
Is groter of gelijk aan |
2 |
<= |
Is kleiner of gelijk aan |
3 |
> |
is groter dan |
4 |
< |
is kleiner dan |
5 |
* |
Bevat |
6 |
!= |
Is niet gelijk aan |
7 |
[] |
is leeg (zie de toelichting hieronder) |
8 |
![] |
is niet leeg (zie de toelichting hieronder) |
9 |
@ |
Start met |
10 |
!* |
Bevat niet |
11 |
!@ |
Start niet met |
12 |
& |
eindigt met |
13 |
!& |
eindigt niet met |
14 |
Sf |
snelfilter |
15 |
Deze operators kun je op de volgende manier toepassen:
AND Filter(OPERATOR)/connectors/XXXXX?filterfieldids=fieldid,fieldid&filtervalues=value,value&operatortypes=type,type
OR Filter(OPERATOR)/connectors/XXXXX?filterfieldids=fieldid;fieldid&filtervalues=value;value&operatortypes=type;type
Sortering
URL/connectors/GetConnectorName?orderbyfieldids=TechnicalFieldId
De Sort operator kan worden gebruikt om een sortering in data aan te brengen. Kies hiervoor een code waarde zoals een ID. Hier zit een goede index op. Standaard staat de sortering op ‘Ascending’. Door een min ‘-‘ voor het veld te plaatsen waar je op filtert sorteer je ‘Decending’.
Skip/Take
URL/connectors/GetConnectorName?skip=0&take=20
De operator Skip/Take geeft de mogelijkheid om data in stukken op te halen. Als de operator niet wordt meegegeven worden altijd de eerste 100 regels teruggegeven. Als je skip en take beide op ‘-1’ instelt worden alle regels opgehaald (niet aanbevolen!).
Gebruik skip/take altijd in combinatie met sortering. De sortering zou anders kunnen wijzigen tijdens het ophalen van de data.
Performance
Zie GetConnector performance optimaliseren
Toelichting bij de operators 8 en 9 (leeg/niet leeg)
Bij deze operator moet altijd een filtervalue worden meegegeven, dit mag een lege value zijn. Bijvoorbeeld:
filterfieldids=PrefixBirthName&operatortypes=8**&filtervalues=""**
UpdateConnector - REST
Een externe applicatie kan records in de Profit-database toevoegen, wijzigen of verwijderen via een UpdateConnector (de mogelijkheden verschillen per connector). Zie verder het overzicht van alle UpdateConnectoren.
Je kunt alleen UpdateConnectoren aanroepen die in de app connector geactiveerd zijn.
Beschikbare methoden:
- POST: gegevens toevoegen (INSERT)
- PUT: gegevens wijzigen (UPDATE)
- DELETE: gegevens verwijderen
Je moet speciale tekens (zoals é, ü, ï) in de indeling UTF-8 aanbieden. Zo niet, dan zie je in Profit een vraagteken in plaats van bijvoorbeeld é, ü, ï.
Metainfo
De Metainfo van een UpdateConnector kan opgevraagd worden via connect.afas.nl.
- Log in op connect.afas.nl
- Ga naar REST/JSON
- Voer de juiste gegevens in (OmgevingsID, type en token)
- Selecteer de UpdateConnector
- Klik op MetaInfo.
Combinatie van PUT en POST
Je kunt in één aanroep gegevens wijzigen en toevoegen. Dit geldt alleen voor connectoren die bestaan uit een hoofdrecord en subrecords.
Het is niet mogelijk om meer dan twee elementen in een webservice-adres toe te voegen.
Het is dus niet mogelijk om bij het onderstaande voorbeeld ook een postadres toe te voegen. Hier moet een aparate REST aanroep-voor worden uitgevoerd.
Mogelijk:
https://xxxxx.rest.afas.online/ProfitRestServices/connectors/KnPerson/KnBasicAddressAdr
Niet mogelijk:
https://xxxxx.rest.afas.online/ProfitRestServices/connectors/KnPerson/KnBasicAddressAdr/KnPerson/KnBasicAddressPad
Response na POST
Na een POST komt er een waarde terug, de response. Zie verder de toelichting hieronder.
Endpoints
POST/PUT = /connectors/{connectorid}
POST/PUT met subelementen = /connectors/{connectorid}/{*subelementids}
DELETE: /connectors/{connectorid}/{elementname}/{fieldids}/{*values}
Voor meer informatie over de endpoints, zie het onderdeel Algemeen.
Voorbeeld: PUT KnPerson
/connectors/KnPerson
Voorbeeld: POST KnPerson
/connectors/KnPerson
Voorbeeld: DELETE KnEmployee
/connectors/KnEmployee/AfasEmployee/@EmId,ViSe/FloorA,U
JSON BODY
Basisvoorbeeld van een POST voor het insturen van een Persoon (KnPerson).
DataConnector - REST
De AFAS API biedt een aantal speciale endpoint aan voor het ophalen van data die niet opgehaald kan worden met de Get Connector. Deze Data Connectoren hebben hun eigen endpoints. Wat betreft filtering en escaping werken deze connectoren gelijk aan de Get Connectoren.
Deze connectoren worden meestal gecombineerd met GetConnectoren om de informatie die nodig is voor de aanroep op te halen. Hiervoor is naast API-kennis ook AFAS-kennis nodig.
VersionConnector
Ophalen van de actieve AFAS-versie.
Zie verder: ProfitVersion-connector
FileConnector
Op basis van een fileID en FileName een bestand ophalen uit een Profit-omgeving.
Zie verder: FileConnector
ImageConnector
Op basis van een imageID en format een afbeelding ophalen uit een Profit-omgeving.
Zie verder: ImageConnector
SubjectConnector
Op basis van een DossieritemID en BestandsID een bestand (bijlage) ophalen uit een Profit-omgeving.
Zie verder: SubjectConnector.
ReportConnector
Op basis van een rapport-guid een rapport genereren.
Zie verder: ReportConnector
Responses
2xx: Successful
Wanneer een call lukt naar de AFAS API komt er een 200 of 201 response. In beide gevallen is de call gelukt. Bij inserts/posts komt er een 201 response wanneer de UpdateConnector een resultaat teruggeeft. Bijvoorbeeld bij een agenda-afspraak. Wanneer deze is aangemaakt krijg je in de response body het afspraaknummer terug.
4xx: Client Error
Http-headers met statussen in de 400 range geven aan dat een request niet bij de server kon aankomen. Specifiek 400: Bad Request en 401: Unauthorized geven altijd aan dat de URL, token of AppConnector niet correct zijn.
5xx: Internal server error
500 Errors ontstaan in de AFAS business rules. De oorzaak hiervan kan divers zijn. Vaak betreft het inhoudelijke foutmeldingen zoals "General message: Om een afspraak aan te maken dienen er genodigden te zijn." Deze melding wordt meegegeven in de Response Header ‘X-Profit-Error’ in Base64 terug. Deze meldingen zijn functioneel en zullen altijd worden afgekeurd.
Retry
Alleen bij meer dan 500 meldingen is het soms handig om een retry te doen. Bijvoorbeeld wanneer je via FiEntries een Update uitvoert en je krijgt een melding terug dat de boekingslayout op dat moment geblokkeerd is door een andere gebruiker. Wat hier gebeurd is dat er vanuit AFAS Profit een mutatie op de boeking plaatsvindt en je dit met de UpdateConnector ook probeert te doen. In dergelijke situaties kun je meerdere retry's uitvoeren totdat de boekingslayout gedeblokkeerd is en de Update wel verwerkt kan worden.
Meer gegevens kunnen gevonden worden in het omgevingslogboek van Profit. De AFAS Beheerder kan je hierin ondersteunen.
FAQ
Hoe weet ik zeker dat mijn request werkt?
Voer een metainfo request uit. Op basis hiervan weet je of de header en het token goed zijn en als response krijg je de Get- en UpdateConnectoren waar je recht op hebt.
Werkt de AFAS API Asynchroon of synchroon?
Synchroon.
Er wordt na het uitvoeren van de request in de AFAS business rules gecontroleerd of de request valide is. Hierna wordt de data opgehaald op aangepast in de database. Hierna komt response terug naar de verbinding die open moet blijven staan in de tussentijd.
Heeft de AFAS API Webhooks?
Er zijn er geen Webhooks beschikbaar.
Hoe kan ik de data in mijn applicatie synchroon houden met AFAS?
Dit doe je door regelmatig te pollen of er nieuwe of gewijzigde records zijn. In bijna alle GetConnector-definities is het mogelijk om de velden ‘aangemaakt op’ en ‘gewijzigd op’ toe te voegen. Door hierop te filteren zorg je dat je alleen de gewijzigde data ophaalt. Hou hierbij rekening met het proces en de AFAS fair use policy.
Beperkingen
Time-out
Als de verbinding met de API langer dan ongeveer 15 minuten actief is, zal er een time-out komen op de call. De volgende methodes kunnen worden toegepast om de time-out te voorkomen:
- Bij een GET kan je filteren of een skip/take met ORDER BY toepassen. Bij een UPDATE kan je de dataset verdelen over meerdere calls. Deze kan je dan ook parallel uitvoeren.
- Gebruik een filter in de call om zo de set van data te managen. Je kunt bijvoorbeeld een filter op periode gebruiken om minder financiële mutaties op halen, In plaats van alle financiële mutaties.
- Verdeel de datasets dan ook over verschillende calls zodat er geen mogelijk probleem komt met de 15 minuten grens.
Data / Fair-Use
Tijdens het ophalen van data hanteert het platform van AFAS Online een fair-use policy. Als er elke minuut dezelfde dataset van 15mb wordt opgehaald als voorbeeld zal hier contact over worden opgenomen.
Filter lengte
Bij het gebruik van de webservices heeft de URL een beperkte lengte. Dit betekent dat de filter mogelijkheden ook beperkt zijn. Het maximaal aantal tekens is 2.048.
Maximale omvang van de take
ls het aantal regels dat wordt opgehaald te groot is, kan er een "Out of Stringspace" of een "Out of memory" foutmelding ontstaan. Om dat te voorkomen, zorg je ervoor dat de Take niet te groot is. Wij adviseren deze deze regel: [Aantal kolommen] x [Aantal regels] < 150.000. Oftewel: kies de Take zo, dat het aantal velden in je GetConnector keer de Take niet groter is dan 150.000. Dit is nu een advies, geen voorschrift. Wel verzoeken we je om je requests na te lopen en waar nodig aan te passen, omdat in de toekomst een limiet aan de maximale omvang van een Get-request ingebouwd zal worden in onze software. Zodra bekend is op welke termijn dit gebeurt, zullen we dit uitgebreid communiceren naar onze klanten.