GraphQL

GraphQL is a query language for APIs that provides a flexible alternative to REST. It allows clients to request precisely the data they need, reducing unnecessary data transfer and multiple requests. This efficiency is particularly useful in querying taxonomy data, where different applications might need varying levels of detail from the same dataset.

Using curl it is quite easy to query the GraphQL endpoints of the taxonomy and save the response in a JSON document. Save the query in a file (in the example below example.graphql is chosen) and call the desired endpoint.

# Get 5 occupation names.
query occupation_names {
  concepts(type: "occupation-name", limit: 5) {
    preferred_label
  }
}
curl --data-urlencode query@example.graphql --get https://taxonomy.api.jobtechdev.se/v1/taxonomy/graphql

The command above should produce output similar to the following JSON.

{
  "data": {
    "concepts": [
      { "preferred_label": "Planeringsarkitekt/Fysisk planerare" },
      { "preferred_label": "Inredningsdesigner" },
      { "preferred_label": "Utvecklingsingenjör, elkraft" },
      { "preferred_label": "Beräkningsingenjör, el-tele" },
      { "preferred_label": "Mjukvaruutvecklare" }
    ]
  }
}

Comparison between REST API and GraphQL API

The table below highlights how common data fetching tasks can be accomplished using either a REST API or a GraphQL API.

Use REST API When:

You need simple, fixed endpoints for specific tasks, such as getting a list of items or details of a single item. You want a straightforward approach to access or modify resources. The operation is focused on a single type of request or a specific, well-defined resource.

Use GraphQL API When:

You need to gather various related pieces of data in a single request, avoiding multiple API calls. You want the flexibility to adjust queries dynamically, asking for only the data you need. You need to fetch interconnected data, such as getting a concept along with its related concepts and changes, in one go.

This table and summary illustrate when each approach is most useful, with specific examples of GraphQL queries highlighting its ability to handle complex and nested data in a single request.

RequestREST APIGraphQL API
Fetch a list of all occupationsGET taxonomy.api.jobtechdev.se/v1/taxonomy/main/concepts?type=occupation-name'query AllOccupations { concepts(type: "occupation-name") { id preferred_label type } }
Fetch a specific occupation by IDGET taxonomy.api.jobtechdev.se/v1/taxonomy/main/concepts?id=occupation-id&type=occupation-namequery specificOccupation { concepts(id: "occupation-id") { id preferred_label type } }
Fetch detailed information about a concept, including related concepts and hierarchyNot feasible in REST without multiple requestsquery ComplexQuery { concepts(id: "concept-id") { id preferred_label type broader { id preferred_label } narrower { id preferred_label } related { id preferred_label } } }

Examples

Fetch tree of occupation-field -> ssyk-level-4 -> occupation-name in version 1.

query occupations {
  concepts(type: "occupation-field", version: "1") {
    id
    preferred_label
    type
    narrower(type: "ssyk-level-4") {
      id
      preferred_label
      type
      narrower(type: "occupation-name") {
        id
        preferred_label
        type
      }
    }
  }
}

Fetch regions and municipalities.

query MyQuery {
  concepts(id: "i46j_HmG_v64") {
    id
    preferred_label
    type
    narrower {
      id
      preferred_label
      type
      narrower {
        id
        preferred_label
        type
      }
    }
  }
}

Fetch related skills to occuaption-name Mjukvaruutvecklare.

query MjukvaruutvecklareSkillsQuery {
  concepts(id: "rQds_YGd_quU") {
    id
    preferred_label
    type
    broader(type: "ssyk-level-4") {
      id
      preferred_label
      type
      related(type: "skill") {
        id
        preferred_label
        type
      }
    }
  }
}

Fetch all changes that has happend to the concept "Utvecklingsingenjör, el-tele".

query MyQuery {
  changelog(id: "Qzzb_67o_n2P") {
    event: __typename
    user
    comment
    timestamp
    concept {
      id
      type
      preferred_label
    }
    ... on Updated {
      changes {
        attribute
        old_value
        new_value
      }
    }
  }
}