Table of Contents
This information applies to all areas of the API for the system. Some of the APIs are "REST" in nature. Other APIs are RPC-over-HTTP in nature. An older API exists which is presented in JSON-RPC.
A client of this system's API may be a desktop application (eg; Haiku Depot) or may be logic in a web page where the web page is using some java-script to call back to the server. It is also possible for other applications to also interact with HDS using its API.
The JSON-RPC API is known as "version 1" and the RPC-over-HTTP is known as "version 2". The latter will eventually completely replace the former. Version 1 is still required for some time until all clients using the version 1 are no longer required.
When objects such as packages or users are referred to in the API, the database primary key is not used. Instead either a natural or artifical identifier is employed. For example, in the case of a package, the package's name may be used. In the case of a screen-shot, a GUID (unique identifier) will be used to identify a particular screenshot.
Reference data means data in the application that is generally invariant. Examples include the mime types, natural language, url types and so on. In these cases, an API will generally provide for access to the list of reference data. The client is expected to obtain such reference data as necessary and cache reference data locally.
The system has only a concept of a "moment in time" which is called a timestamp. The timestamp is typically communicated as the number of milliseconds elapsed since the epoc represented as a 64bit integer. The timestamp communicated via the API is always relative to UTC.
The term "invocation" refers to a request-response cycle from the client software into the application server over the HTTP protocol. Each API invocation is made in a stateless manner in that each invocation is not dependent on the prior invocation.
See the security chapter for details on how to authenticate API requests as well as how API requests are authorized.
This header is only observed in some APIs where large quantities of data are being downloaded or where the data is computationally expensive to assemble. Examples of these situations include the assembly of a tar-ball of pacakges' icons or the download of bulk package data.
In order to prevent clients from downloading and processing data they already have, the client may add a "If-Modified-Since" header to the initial request. The form of this header is RFC-1123 compliant and looks like "Sat, 3 Dec 2016 23:48:05 GMT". Taking the example of downloading a tar-ball of icon data; if the icon data has not been modified since the "If-Modified-Since" header time, then the API will return a 304 (Not Modified) response.
This API is achieved by sending JSON payloads over HTTP. The request is expressed as JSON and the response is also expressed as JSON. The request is a JSON object with key-value pairs of data. The response has the following shape;
{ "result": { "code": "beam", "name": "Beam Email Program" } }
In the event that there is an error, this is expressed in the response as follows;
{ "error": { "code": 12345, "message": "Something has gone wrong", "data": [ { "key": "something", "value": "Feet" } ] } }
One can find the definitions for the APIs in Open-API format in the source code in the module "haikudepotserver-api2".
A set of known RPC error codes are agreed between the client and server. See the RPC specification for known error codes used for transport-related issues such as invalid parameters. Application-specific error codes are documented in the java source at "org.haiku.haikudepotserver.api1.support.Constants".
Some errors such as the validation error (code -32800) may also carry additional data that provides detail as to the nature of the error that has arisen. Java logic for assembling the error payloads can be found at "org.haiku.haikudepotserver.api1.support.ErrorResolverImpl".
The RPC-over-REST API is expressed as Open-API specifications. These specifications can be used to generate code that represents a client. To generate a client for the Python language, issue the following commands from the top level of the project;
./mvnw --projects haikudepotserver-api2 package -Ppython
The resulting code can be found at "./haikudepotserver-api2/target/generated-sources/openapi/openapi_client".
Some requests are instant and some take some time to complete. An example of an instant API is fetching the details of a user. An example of a request that may take some time is producing an archive of all of the icons for all packages in the system.
For the long-run requests the HDS API system provides an asynchronous interface with a generalized pattern of interaction. This section covers how to use this pattern. The pattern generally follows the following steps;
Details about the specific API call signatures for any API with paths "/__api/..." can be obtained from the Open-API specification in the "haikudepotserver-api2" module.
Some jobs may require data to be provided. An example of this might be where a tar-ball of screenshots is uploaded to be imported. In this case, HDS provides an API to upload the data which will then return a data code. Where required, the data code can be used with the API to start a job. To access the data upload function, invoke a POST request to "/__secured/jobdata". The API call will return the data code in a response header "X-HaikuDepotServer-DataGuid".
Some of the data transfer objects (DTO) in the system are generated. This means that a software artifact is stored in the project and the java objects that are used in the running software are generated from the schema document. In the java environment this is done using maven plugins, but it is also made possible in the C++ environment too. Python scripts are provided to cater for this.
The HaikuDepot build system will use the schema to generate C++ objects. You can find this in the "build" directory of the HaikuDepot source. The schema are read and are trans-coded to C++ using Python scripts. The schema files are copied manually from HDS to the HaikuDepot source.
REST API is generally required where data is inappropriate to encode as JSON-RPC. This tends to be situations where the data is binary in nature or where data is large in size. An example of this is where a package icon needs to be uploaded or where bulk packages' data should be returned.
This API will provide the web application's HTML user interface.
This API provides a mechanism by which an external client is able to trigger the application to start importing package-related data from a remote repository. This API is provided as REST because the client is likely to be scripted using a scripting language and REST is the most appropriate protocol to employ in this situation. This invocation will trigger the import process, but the import process will execute in a background thread in the application server and will not block the client.
In order to prevent the possibility of this API causing undue load on the application server, it will coalesce overlapping requests. This means that if a succession of requests come in requesting that the repository "xyz" is imported then onle the first one will be honoured and only after the first one is completed with another be accepted.
It is possible for an administrator to configure a password on the Repository. If this is the case then this API will require a Basic authentication header to be sent to authenticate the request with the configured password. The username provided in the Basic authentication header is ignored.
Example 12.1. Example: Prompt Repository Update
In this example, a remote system build script has just completed the assembly of repository and would now like to prompt HDS to import the HPKR data for processing. The Repository and the RepositorySource are correctly configured on the HDS system. The Repository code is "haikuports" and the RepositorySource is "haikuports_x86_64". Using the CURL command, HDS could be prompted as follows;
curl -X POST \ -u ":password" \ "http://depot.haiku-os.org/__repository/haikuports/source/haikuports_x86_64/import"
This API is able to provide the icon for a package. If there is no icon stored then this method will provide a fall-back image if the "f" query parameter is configured to "true" — otherwise it will return a 404 HTTP status code. Providing a fallback image may not be possible in all cases. The request will return a "Last-Modified" header. The timestamps of this header will correlate to the "modifyTimestamp" that is provided in API responses such as "GetPkResult" and "SearchPkgsResult". The value for "modifyTimestamp" will be at millisecond resolution, but the HTTP headers will be at second resolution. The path includes a "mediatype-extension" which can have one of the following values;
Details of the API;
An example URL for obtaining a bitmap image would be "http://localhost:8080/__pkgicon/apr.png?size=32&f=true".
An example URL for obtaining a Haiku vector image file image would be "http://localhost:8080/__pkgicon/apr.hvif"
This API is able to generate a "tar-ball" containing all of the icon data together with some meta-data about the icons. Note that the data will be compressed using gzip compression. After making this call, the client may be redirected to a different URL to actually access the data. Clients should not make assumptions about the form of the redirected URL.
This API supports the If-Modified-Since header.
The tar-ball contains a file "info.json" which has a field "dataModifyTimestamp" that can be used to form the "If-Modified-Since". Otherwise, the file contains each entry in the form "hicn/<package-name>/<icon-leaf>.<extension>". Possible values for the extension are;
The icon-leaf may be "icon" in the case of HVIF data or in the case of a bitmap icon, the icon-leaf will be the size of the image; for example 16, 32 or 64.
Details of the API;
This API is able to provide all of the packages' details sufficient for running the desktop application.
This API supports the If-Modified-Since header.
The resultant data transfer objects (DTO) used in this API are available as a json schema within the source.
Details of the API;
This API is able to generate a JSON payload containing reference data for selected pieces of information in the system such as Countries, Natural Languages and Package Categories. This can then be used in applications such as HaikuDepot in order to support provision of choices for the user in drop-down lists etc...
This API supports the If-Modified-Since header.
The resultant data transfer objects (DTO) used in this API are available as a json schema within the source.
Details of the API;
This API is able to generate a large JSON payload containing details regarding each active repository. Note that the path contains a natural language code such as "de" but at the time of writing there is no support for localizing this information.
This API supports the If-Modified-Since header.
The resultant data transfer objects (DTO) used in this API are available as a json schema within the source.
Details of the API;
This API is able to produce an image for a screenshot. The screenshot is identified in the path by its code. The response will return a "Last-Modified" header. The timestamps of this header will correlate to the "modifyTimestamp" that is provided in API responses such as "GetPkResult" and "SearchPkgsResult". The value for "modifyTimestamp" will be at millisecond resolution, but the HTTP headers will be at second resolution. Requests for screenshot image should be accompanied by a target width and height. These values must be within a range of 1..1500. The image will maintain its aspect ratio as it is scaled to fit within the supplied target width and height.
An example URL is "http://localhost:8080/pkgscreenshot/a78hw20fh2p20fh122jd92.png?tw=640&th=480".
This API is able to provide the raw screenshot data.
An example URL is "http://localhost:8080/__pkgscreenshot/a78hw20fh2p20fh122jd92/raw".
This API is able to add an image as a screenshot for the nominated package. The screenshot will be ordered last. The payload of the POST must be a PNG image that is a maximum of 1500x1500 pixels and a maximum of 2MB in size.
An example URL is "http://localhost:8080/__pkgscreenshot/apr/add?format=png".