Get introduced to the API Service
Introduction
The API towards Danløn is exposed as a GraphQL API.
In comparison to a traditional REST interface, GraphQL provides greater freedom and flexibility to API clients (API users). With GraphQL, clients can query the exact data needed (at the field level), just as it is possible to put together complex data structures in a single query. As an example, it is possible to retrieve information about both a company and the company's employees in a single query.
If there is no need for the company's employees, this is simply omitted from the request. If both employees and for example mailing addresses of employees are included in the query, this data will be returned, still in a single call to the API.
You can read more about GraphQL on the official site.
There is also an introduction to GraphQL that will give you a basic understanding.
To summarize, a service is defined by the types it accepts as input and returns as output. These types include fields that are themselves types. This information is kept in a formal schema that allows for features such as auto-completion when writing queries, and syntax checking before the query reaches the server.
Another key point is that GraphQL defines three types of services: Queries, mutations and subscriptions.
Queries are used to retrieve (get) data, while mutations are used when resources should be modified.
Subscriptions are not used in this API in this version but are used to provide real time event to clients (think WebSockets).
Get started
A quick way to get started using the API, verifying that both an access token and the query syntax is valid, is to use the provided playground.
In the area on the left, you enter the query you want to perform. By pressing the play button, the result will be displayed in the area on the right.
At the bottom, it is possible to insert query variables and http headers. This will be explained in greater detail later.
Security
The API security is based on http authorization header tokens, and it is therefore necessary to have a valid access token to call the API.
Obtaining an Access Token
Once a refresh token has been obtained by a user who has connected our two applications, an access token can be obtained by using the following curl:
curl --location --request POST 'https://auth.lessor.dk/auth/realms/danlon-integration-demo/protocol/openid-connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=refresh_token' \
--data-urlencode 'client_id=' \
--data-urlencode 'client_secret=' \
--data-urlencode 'refresh_token='
Authorization Header
To use a token in the API, an Authorization header bearer token is used. In 'Http Headers' at the bottom of the Playground, insert the access token to be used in json format as follows:
{
"Authorization": "Bearer "
}
This will include the token in the authorization http header when performing the call.
Services
The API includes services to get employees, companies and pay parts, including pay part metadata (all as queries), and services to create and delete pay parts (mutations).
Calling the API programmatically
How to best call the API from code varies from programming language to programming language, but common for all technologies is that the API is called over an HTTP connection by posting JSON based content and HTTP headers.
To get an understanding of how this can be done, the playgrounds 'copy curl' functionality can be used. By pressing this button, a curl command with the current content is copied into the clipboard.
For example, the following query with an Authorization Bearer header token translates into the following curl.
Query:
{ companies { id name } }
Curl:
curl 'https://api-demo.danlon.dk/graphql' -H 'Accept-Encoding: gzip, deflate, br' -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Connection: keep-alive' -H 'DNT: 1' -H 'Origin: http://api.integration.dev-lessor.dk' -H 'Authorization: Bearer ' --data-binary '{"query":"{ companies { id name } }"}' –compressed
An in dept explanation of how to access a GraphQL api using your favorite technological stack is beyond the scope of this guide, but hopefully this has given enough ideas and pointers to get you started.
And of course, the API team is always ready to help by answering any questions you may have.
Employees
The employee service is defined as a type placed under companies. To get the employee for a given company, all that is needed is to request the employees from the company:
query($company_id: ID!) {
companies(company_ids: [$company_id]) {
id
name
employees {
id
name
}
}
}
As with companies it is possible to filter on employee ids:
query($company_id: ID!, $employee_id:ID!) {
companies(company_ids: [$company_id]) {
id
name
employees(employee_ids: [$employee_id]) {
id
name
}
}
}
Company
The company service is used to retrieve information about a user’s companies. A very simple query that retrieves the list of companies and their ids and names, looks like this:
query {
companies {
id
name
}
}
Note that more fields exist on a company, and that the playground supports auto completion to help build queries safely and quickly.
In this example, there is only one company for the given user, but if there are more than one, it might be preferable to filter the returned companies.
This can be done by specifying the list of company ids we wish to return:
query {
companies(company_ids: ["MjAwMDAwXzMwMDAwMA=="]) {
id
name
}
}
An even better approach would be to use query variables. Using query variables can help improve performance on the server, as the query only needs to be passed once (each query will be passed separately, even if the queries only differ on input values).
To use variables, we define the variables we wish to use in the query and apply the values for the variables in the 'Query Variables' pane. Such a query looks like this:
query($company_id: ID!) {
companies(company_ids: [$company_id]) {
Version number: 4
Date: 14th April 2021
6
id
name
}
}
As mentioned, the variables values are defined in the query variables pane as in the following json:
{
"company_id": "MjAwMDAwXzMwMDAwMA=="
}
In the playground, it looks like this:
Pay Parts
There are several ways to retrieve pay parts.
1. Using the company query, getting a list of all pay parts for a company
2. Using the employee query under a company, getting all pay parts for an employee
3. Using the pay_parts query, getting a list of all pay parts for a company
All three methods return the same data, and only vary slightly in how the result is returned.
To create or delete pay parts, only the pay_parts mutation can be used.
Retrieving Pay Parts for a Company
A query to get a list of pay parts for a company looks as follows:
query($company_id: ID!) {
companies(company_ids: [$company_id]) {
id
name
pay_parts {
code
units
rate
amount
employee {
id
name
}
}
}
}
Retrieving Pay Parts for an Employee
A query to get a list of pay parts for a specific employee looks as follows:
query($company_id: ID!, $employee_id: ID!) {
companies(company_ids: [$company_id]) {
id
name
employees(employee_ids: [$employee_id]) {
pay_parts {
code
units
rate
amount
}
}
}
}
Retrieving Pay Parts using Pay Parts Resource
query($company_id: ID!) {
pay_parts(company_id: $company_id) {
code
units
rate
amount
employee {
id
}
}
}
Creating Pay Parts for a Company and an Employee
To create pay parts, a mutation under the PayParts resource is used (note that it is possible to create more than one pay part in a single call, as the input type accepts a list):
mutation($company_id: ID!, $employee_id: ID!) {
create_pay_parts(
company_id: $company_id
pay_parts: [
{
employee_id: $employee_id
code: "T1"
units: 200
rate: 300
amount: 500
}
]
) {
id
}
}
Deleting Pay Parts
To delete pay parts, a mutation under the PayParts resource is used (again the input is of type list, so multiple pay parts can be deleted):
mutation($company_id: ID!, $pay_part_id: ID!) {
delete_pay_parts(company_id: $company_id, pay_part_ids: [$pay_part_id])
}
Pay Parts Meta Data
To retrieve a list of the valid pay part meta data including codes, descriptions and which attributes on each code that are mandatory or forbidden, the PayParts MetaData resource can be used:
{
pay_parts_meta {
code
description
units_allowed
rate_allowed
amount_allowed
}
}
Current Company
To retrieve the current company id, the following query can be used:
{current_company{id}}