OpenProject is the leading open source project management software.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
openproject/frontend/doc/API.md

4.5 KiB

API Handling

In general, the OpenProject Frontend uses all of the existing working APIs to provide its functionality, as the current working version for APIv3 is not feature complete.

The documentation for these APIs and their capabilities:

  • APIv3
  • APIv2 docs are located in the opf/openproject repository at ./doc/apiv2-documentation.md
  • There is no documentation on the experimental API

To get a feeling for which API is used at which point, please refer to the PathHelper located at ./frontend/app/helpers/path-helper.js. It is used throughout the application to centralize knowledge about paths.

HAL

While having a PathHelper certainly helps, the long-term idea is to leverage the HAL-capabilities of the APIv3 (thereby leaving v2 and experimental behind) to let any client discover the paths available for a resource by inspecting the responses from any given call.

Note: All responses from the APIv3 are thereby of Content-Type: application/hal+json and not just Content-Type: application/json. Some developer client tools sometimes get confused with that and will not interpret the formatting correctly.

Example:

// calling a project

{
    "_type": "Project",
    "_links": {
        "self": {
            "href": "/api/v3/projects/1",
            "title": "Lorem"
        },
        "createWorkPackage": {
            "href": "/api/v3/projects/1/work_packages/form",
            "method": "post"
        },
        "createWorkPackageImmediate": {
            "href": "/api/v3/projects/1/work_packages",
            "method": "post"
        },
        "categories": { "href": "/api/v3/projects/1/categories" },
        "types": { "href": "/api/v3/projects/1/types" },
        "versions": { "href": "/api/v3/projects/1/versions" }
    },
    "id": 1,
    "identifier": "project_identifier",
    "name": "Project example",
    "description": "Lorem ipsum dolor sit amet"
}

The Project structure contains links to ressources associated. Given the knowledge about _links, one may easily infer the path from the response:

// some magic to retrieve an object, note that the services used are examplary 
// and can not be found in the actual codebase
ProjectsService.getProject('project_identifier').then(function(project) {
    var pathToVersions = project._links.versions.href;
    // the VersionsService has knowledge about pathToVersions in its 
    // forProject method
    VersionsService.forProject(project).then(function(versions) {
        // versions should be the result of the call to pathtoVersions
        console.log(versions);
    });
});

This is in principle a very good concept to delegate responsibility of inference to the client and absolves the client of having to know each path in the application in advance.

Using hyperagent.js

For all practical purposes, the OpenProject frontend uses a fork of hyperagent.js (actually this one is used).

hyperagent.js aims to provide an interface to a structed JSON response, providing a resource object automatically. While this is a nice goal, the current implementation used is not complete.

The library has been wrapped as a service in ./frontend/app/api/hal-api-resource.js and can be injected when needed.

What the service actually does is making resource objects out out of certain API responses (v3 only) and providing LazyResources to attached links. This is also the difference to using _links and links as a property sometimes:

//@see ./frontend/app/work_packages/services/work-package-attachments-service.js

// `workPackage` Hyperagent resource
var addAttachmentPath = workPackage.links.addAttachment.url();

// `workPackage` is an API response
var addAttachmentPath = workPackage._links.addAttachment.href;

One of the minor drawbacks of hyperagent.js is that it (read: the fork used) only supports GET requests at the moment and one has to awkwardly inject the method desired into the options of the AJAX call made (see also the setup method of hal-api-resource.js, as well as an example in loadWorkPackageForm in ./frontend/app/services/work-package-service.js).

Note: The long term goal should be to leverage angular.$http and make the calls accordingly. One of the short term goals should be to remove duplication introduced when building requests via the HALAPIResource.