Table of Contents

Introduction

The search service supports searching for resources inside a company. The basic operation is to POST a search object that will be processed accordingly. There are two kinds of searches; free-form searches and structured searches. Free-form is useful when the query is from a human and you want Fiken to take care of searching in as many places as possible. There are not many ways the question can be limited. The structured search is for searching specific fields for specific values and are useful for machines looking for specific data.

You can search across all collections at once, or you can specify what collection and field you would like to search. For instance on Products, you can search for a productNumber, to more easily find a product for creating an invoice, or register Contacts with a organizationIdentifier, which allows you to quickly search them back up again later.

Searching across all collections

A search that queries for objects that matches the string test. This will search in many types of resources and most of their fields.

Exchange #1

Request
POST https://.../url-1
Accept: application/hal+json, application/vnd.error+json
Content-Type: application/hal+json

{
  "query": "test"
}
Response
200 OK
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: ...
Content-Type: application/hal+json;charset=UTF-8
Date: ...
Expires: Thu, 01 Jan 1970 00:00:00 GMT
X-Request-ID: <random UUID>

{
  "_links": {},
  "_embedded": {
    "https://fiken.no/api/v1/rel/contacts": [
      {
        "_links": {
          "self": {
            "href": "https://.../url-2"
          }
        },
        "name": "Test Testesen",
        "address": {
          "country": "Norge"
        },
        "customerNumber": 10027
      },
      {
        "_links": {
          "self": {
            "href": "https://.../url-3"
          }
        },
        "name": "Scenario test customer",
        "email": "test1@fiken.no",
        "address": {
          "country": "Norge"
        },
        "customerNumber": 10031
      },
      {
        "_links": {
          "self": {
            "href": "https://.../url-4"
          }
        },
        "name": "Test Testesen",
        "address": {
          "country": "Norge"
        },
        "customerNumber": 10034,
        "memberNumber": "123456"
      }
    ],
    "https://fiken.no/api/v1/rel/products": [
      {
        "_links": {
          "self": {
            "href": "https://.../url-5"
          }
        },
        "name": "Testprodukt #8",
        "unitPrice": 10696,
        "incomeAccount": "3000",
        "vatType": "HIGH",
        "active": true,
        "stock": -1.6000000000,
        "productNumber": "8"
      },
      {
        "_links": {
          "self": {
            "href": "https://.../url-6"
          }
        },
        "name": "Testprodukt #9",
        "unitPrice": 12033,
        "incomeAccount": "3030",
        "vatType": "MEDIUM",
        "active": true,
        "stock": -8.3000000000,
        "productNumber": "9"
      },
      {
        "_links": {
          "self": {
            "href": "https://.../url-7"
          }
        },
        "name": "Testprodukt #1",
        "unitPrice": 1337,
        "incomeAccount": "3030",
        "vatType": "MEDIUM",
        "active": true,
        "stock": -52.7000000000,
        "productNumber": "1"
      },
      {
        "_links": {
          "self": {
            "href": "https://.../url-8"
          }
        },
        "name": "Testprodukt #2",
        "unitPrice": 2674,
        "incomeAccount": "3000",
        "vatType": "HIGH",
        "active": true,
        "stock": -31.4000000000,
        "productNumber": "2"
      },
      {
        "_links": {
          "self": {
            "href": "https://.../url-9"
          }
        },
        "name": "Testprodukt #3",
        "unitPrice": 4011,
        "incomeAccount": "3030",
        "vatType": "MEDIUM",
        "active": true,
        "stock": 1.9000000000,
        "productNumber": "3"
      },
      {
        "_links": {
          "self": {
            "href": "https://.../url-10"
          }
        },
        "name": "Testprodukt #4",
        "unitPrice": 5348,
        "incomeAccount": "3000",
        "vatType": "HIGH",
        "active": true,
        "stock": -79.8000000000,
        "productNumber": "4"
      },
      {
        "_links": {
          "self": {
            "href": "https://.../url-11"
          }
        },
        "name": "Testprodukt #5",
        "incomeAccount": "3030",
        "vatType": "MEDIUM",
        "active": true,
        "stock": 4.5000000000,
        "productNumber": "5"
      },
      {
        "_links": {
          "self": {
            "href": "https://.../url-12"
          }
        },
        "name": "Testprodukt #6",
        "unitPrice": 8022,
        "incomeAccount": "3000",
        "vatType": "HIGH",
        "active": true,
        "stock": 5.8000000000,
        "productNumber": "6"
      },
      {
        "_links": {
          "self": {
            "href": "https://.../url-13"
          }
        },
        "name": "Testprodukt #7",
        "unitPrice": 9359,
        "incomeAccount": "3030",
        "vatType": "MEDIUM",
        "active": true,
        "stock": -75.9000000000,
        "productNumber": "7"
      }
    ]
  }
}

Limiting open searches to some collections

If you know what kind of resource you want, you can limit the search to a subset of the available collections:

Exchange #2

Request
POST https://.../url-1
Accept: application/hal+json, application/vnd.error+json
Content-Type: application/hal+json

{
  "collections": [
    "https://.../url-14",
    "https://.../url-15"
  ],
  "query": "test"
}
Response
200 OK
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: ...
Content-Type: application/hal+json;charset=UTF-8
Date: ...
Expires: Thu, 01 Jan 1970 00:00:00 GMT
X-Request-ID: <random UUID>

{
  "_links": {},
  "_embedded": {
    "https://fiken.no/api/v1/rel/contacts": [
      {
        "_links": {
          "self": {
            "href": "https://.../url-2"
          }
        },
        "name": "Test Testesen",
        "address": {
          "country": "Norge"
        },
        "customerNumber": 10027
      },
      {
        "_links": {
          "self": {
            "href": "https://.../url-3"
          }
        },
        "name": "Scenario test customer",
        "email": "test1@fiken.no",
        "address": {
          "country": "Norge"
        },
        "customerNumber": 10031
      },
      {
        "_links": {
          "self": {
            "href": "https://.../url-4"
          }
        },
        "name": "Test Testesen",
        "address": {
          "country": "Norge"
        },
        "customerNumber": 10034,
        "memberNumber": "123456"
      }
    ],
    "https://fiken.no/api/v1/rel/products": [
      {
        "_links": {
          "self": {
            "href": "https://.../url-5"
          }
        },
        "name": "Testprodukt #8",
        "unitPrice": 10696,
        "incomeAccount": "3000",
        "vatType": "HIGH",
        "active": true,
        "stock": -1.6000000000,
        "productNumber": "8"
      },
      {
        "_links": {
          "self": {
            "href": "https://.../url-6"
          }
        },
        "name": "Testprodukt #9",
        "unitPrice": 12033,
        "incomeAccount": "3030",
        "vatType": "MEDIUM",
        "active": true,
        "stock": -8.3000000000,
        "productNumber": "9"
      },
      {
        "_links": {
          "self": {
            "href": "https://.../url-7"
          }
        },
        "name": "Testprodukt #1",
        "unitPrice": 1337,
        "incomeAccount": "3030",
        "vatType": "MEDIUM",
        "active": true,
        "stock": -52.7000000000,
        "productNumber": "1"
      },
      {
        "_links": {
          "self": {
            "href": "https://.../url-8"
          }
        },
        "name": "Testprodukt #2",
        "unitPrice": 2674,
        "incomeAccount": "3000",
        "vatType": "HIGH",
        "active": true,
        "stock": -31.4000000000,
        "productNumber": "2"
      },
      {
        "_links": {
          "self": {
            "href": "https://.../url-9"
          }
        },
        "name": "Testprodukt #3",
        "unitPrice": 4011,
        "incomeAccount": "3030",
        "vatType": "MEDIUM",
        "active": true,
        "stock": 1.9000000000,
        "productNumber": "3"
      },
      {
        "_links": {
          "self": {
            "href": "https://.../url-10"
          }
        },
        "name": "Testprodukt #4",
        "unitPrice": 5348,
        "incomeAccount": "3000",
        "vatType": "HIGH",
        "active": true,
        "stock": -79.8000000000,
        "productNumber": "4"
      },
      {
        "_links": {
          "self": {
            "href": "https://.../url-11"
          }
        },
        "name": "Testprodukt #5",
        "incomeAccount": "3030",
        "vatType": "MEDIUM",
        "active": true,
        "stock": 4.5000000000,
        "productNumber": "5"
      },
      {
        "_links": {
          "self": {
            "href": "https://.../url-12"
          }
        },
        "name": "Testprodukt #6",
        "unitPrice": 8022,
        "incomeAccount": "3000",
        "vatType": "HIGH",
        "active": true,
        "stock": 5.8000000000,
        "productNumber": "6"
      },
      {
        "_links": {
          "self": {
            "href": "https://.../url-13"
          }
        },
        "name": "Testprodukt #7",
        "unitPrice": 9359,
        "incomeAccount": "3030",
        "vatType": "MEDIUM",
        "active": true,
        "stock": -75.9000000000,
        "productNumber": "7"
      }
    ]
  }
}

Searching for a value in one collection

You can also search a single collection across all fields for a value:

Exchange #3

Request
POST https://.../url-1
Accept: application/hal+json, application/vnd.error+json
Content-Type: application/hal+json

{
  "collection": "https://.../url-14",
  "query": "123456"
}
Response
200 OK
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: ...
Content-Type: application/hal+json;charset=UTF-8
Date: ...
Expires: Thu, 01 Jan 1970 00:00:00 GMT
X-Request-ID: <random UUID>

{
  "_links": {},
  "_embedded": {
    "https://fiken.no/api/v1/rel/contacts": [
      {
        "_links": {
          "self": {
            "href": "https://.../url-4"
          }
        },
        "name": "Test Testesen",
        "address": {
          "country": "Norge"
        },
        "customerNumber": 10034,
        "memberNumber": "123456"
      }
    ]
  }
}

Searching for a value in a specific field

On the other hand it can be useful to be able to do more specific searches. If you know the collection that contain the resource you're after and the value of a field, specify that with a collection and the field:

Exchange #4

Request
POST https://.../url-1
Accept: application/hal+json, application/vnd.error+json
Content-Type: application/hal+json

{
  "collection": "https://.../url-14",
  "field": "memberNumber",
  "query": "123456"
}
Response
200 OK
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: ...
Content-Type: application/hal+json;charset=UTF-8
Date: ...
Expires: Thu, 01 Jan 1970 00:00:00 GMT
X-Request-ID: <random UUID>

{
  "_links": {},
  "_embedded": {
    "https://fiken.no/api/v1/rel/contacts": [
      {
        "_links": {
          "self": {
            "href": "https://.../url-4"
          }
        },
        "name": "Test Testesen",
        "address": {
          "country": "Norge"
        },
        "customerNumber": 10034,
        "memberNumber": "123456"
      }
    ]
  }
}

Technical Details

Collections

The search service introduces the term collections. A collection in this context means "all sales", "all contacts" for a specific company. To find the URL to a particular company's collection, start with the company's resource and use the rel to look up the URL from the _links object.

Free-form Searches

The free-form search is an unstructured query string in a similar style to what Google and other search services do.

To do a free-form search send a Json object with a query key. The search response object does not have any items on its own, but embeds other resources. The relations are the same as used elsewhere.

Searchable Collections and Fields

These collections and fields are available for the search service

Contact: supplierNumber, customerNumber, memberNumber, name, organizationIdentifier, and email.

Sale: saleNumber

Product: name and productNumber

Note that other collections and fields will be available later on which may change the results returned from a query.