Last updatedOct 22, 2019

Response object hydration

Object hydration allows your app to respond to proxied API requests with a minimal amount of data for a resource and Bitbucket will add the full object from the Bitbucket database. This API proxy service will automatically fill in any missing elements of certain Bitbucket data types returned by a remote service. This allows remote services to keep track of only the absolute minimum information to uniquely identify an object.

For example, if your app were meant to get details of a single repository it only has to store a way to identify the repository, which can be as little as a repository UUID. Without using the proxy module, a simple request using a repository UUID returns a partial repository response object, without being hydrated, that would look like this:

1
2
3
4
{
  "type": "repository",
  "uuid": "{aa5acc33-e5f7-43e9-883d-50325fc68ca8}"
}

Using the proxy module, when the response is passed to Bitbucket's API proxy, the proxy:

  1. Decodes the JSON from the remote service.
  2. Scans the object graph for type elements defined in Bitbucket.
  3. For each type, queries the database and substitutes it for the full object.
  4. Serializes the resulting object, producing layouts consistent with other, core APIs.

The hydrated response coming from the API proxy provided to the client would look like the entire response body from the repository endpoint.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
{
    "scm": "git",
    "website": "",
    "has_wiki": false,
    "uuid": "{aa5acc33-e5f7-43e9-883d-50325fc68ca8}",
    "links": {
        "watchers": {
            "href": "https://api.bitbucket.org/2.0/repositories/atlassian_tech_writing/teams-in-space-tutorial-content/watchers"
        },
        "branches": {
            "href": "https://api.bitbucket.org/2.0/repositories/atlassian_tech_writing/teams-in-space-tutorial-content/refs/branches"
        },
        "tags": {
            "href": "https://api.bitbucket.org/2.0/repositories/atlassian_tech_writing/teams-in-space-tutorial-content/refs/tags"
        },
        "commits": {
            "href": "https://api.bitbucket.org/2.0/repositories/atlassian_tech_writing/teams-in-space-tutorial-content/commits"
        },
        "clone": [
            {
                "href": "https://bitbucket.org/atlassian_tech_writing/teams-in-space-tutorial-content.git",
                "name": "https"
            },
            {
                "href": "git@bitbucket.org:atlassian_tech_writing/teams-in-space-tutorial-content.git",
                "name": "ssh"
            }
        ],
        "self": {
            "href": "https://api.bitbucket.org/2.0/repositories/atlassian_tech_writing/teams-in-space-tutorial-content"
        },
        "source": {
            "href": "https://api.bitbucket.org/2.0/repositories/atlassian_tech_writing/teams-in-space-tutorial-content/src"
        },
        "html": {
            "href": "https://bitbucket.org/atlassian_tech_writing/teams-in-space-tutorial-content"
        },
        "avatar": {
            "href": "https://bitbucket.org/atlassian_tech_writing/teams-in-space-tutorial-content/avatar/32/"
        },
        "hooks": {
            "href": "https://api.bitbucket.org/2.0/repositories/atlassian_tech_writing/teams-in-space-tutorial-content/hooks"
        },
        "forks": {
            "href": "https://api.bitbucket.org/2.0/repositories/atlassian_tech_writing/teams-in-space-tutorial-content/forks"
        },
        "downloads": {
            "href": "https://api.bitbucket.org/2.0/repositories/atlassian_tech_writing/teams-in-space-tutorial-content/downloads"
        },
        "pullrequests": {
            "href": "https://api.bitbucket.org/2.0/repositories/atlassian_tech_writing/teams-in-space-tutorial-content/pullrequests"
        }
    },
    "fork_policy": "allow_forks",
    "name": "Teams In Space Tutorial Content",
    "project": {
        "key": "PROJ",
        "type": "project",
        "uuid": "{a18967d5-acba-4f73-bf9c-36d9fa6ea143}",
        "links": {
            "self": {
                "href": "https://api.bitbucket.org/2.0/teams/atlassian_tech_writing/projects/PROJ"
            },
            "html": {
                "href": "https://bitbucket.org/account/user/atlassian_tech_writing/projects/PROJ"
            },
            "avatar": {
                "href": "https://bitbucket.org/account/user/atlassian_tech_writing/projects/PROJ/avatar/32"
            }
        },
        "name": "Atlassian Tech Writing Scripts"
    },
    "language": "",
    "created_on": "2015-08-14T01:18:36.773253+00:00",
    "mainbranch": null,
    "full_name": "atlassian_tech_writing/teams-in-space-tutorial-content",
    "has_issues": false,
    "owner": {
        "username": "atlassian_tech_writing",
        "display_name": "Atlassian Technical Writing",
        "type": "team",
        "uuid": "{bb95f287-ac12-4a77-986f-7a5208f81c5e}",
        "links": {
            "self": {
                "href": "https://api.bitbucket.org/2.0/teams/atlassian_tech_writing"
            },
            "html": {
                "href": "https://bitbucket.org/atlassian_tech_writing/"
            },
            "avatar": {
                "href": "https://bitbucket.org/account/atlassian_tech_writing/avatar/32/"
            }
        }
    },
    "updated_on": "2015-08-14T07:19:10.128919+00:00",
    "size": 33348,
    "type": "repository",
    "slug": "teams-in-space-tutorial-content",
    "is_private": false,
    "description": "This repository is for storing demo content that can be access for tutorials within product documentation."
}

Capturing the parent object of the object you're capturing

For objects that belong to another object -- like how a repository belongs to a user or team -- the parent object may need to be resolved in order to resolve a child object.

One exception to this is resolving repository objects. If you resolve a repository object using a repository UUID you don't need to resolve the account it belongs to. The UUID of a repository alone is enough to resolve a repository object. You might prefer to resolve repositories using a UUID because it's less data for an application to track, or because a repository can still be resolved if it is transferred between accounts.

Alternatively, if a repository slug is being used to resolve a repository object you will still need to resolve the account a repository object belongs to (the parent object) so Bitbucket can identify the repository.

Response objects that can be hydrated

The response objects listed below are the Bitbucket objects that can be hydrated.

For objects with multiple schemas, you could use any of the listed schemas.

Issue schema

1
2
3
4
5
{
  "type": "issue",
  "id": issue id, // int
  "repository": *repository schema
}

Snippet schema

1
2
3
4
{
  "type": "snippet",
  "id": snippet id // unicode
}

Pull request schema

1
2
3
4
5
6
7
{
  "type": "pullrequest",
  "id": pullrequest id, // int
  "destination": {
    "repository": *repository schema
  }
}

* See repository schemas.

Repository schemas

1
2
3
4
{
  "type": "repository",
  "uuid": repository uuid // unicode
}
1
2
3
4
{
  "type": "repository",
  "full_name": repository fullname // unicode
}
1
2
3
4
5
{
  "type": "repository",
  "slug": repository slug, // unicode
  "owner": *account schema
}

* See account schemas.

Account schemas

Account (user) schemas

1
2
3
4
{
  "type": "user",
  "uuid": user uuid // unicode
}
1
2
3
4
{
  "type": "user",
  "account_id": user account id // unicode
}

Account (team) schemas

1
2
3
4
{
  "type": "team",
  "uuid": team uuid // unicode
}
1
2
3
4
{
  "type": "team",
  "username": team username // unicode
}
1
2
3
4
{
  "type": "team",
  "account_id": team account id // unicode
}

Project schemas

1
2
3
4
{
  "type": "project",
  "uuid": project uuid // unicode
}
1
2
3
4
5
{
  "type": "project",
  "key": project key, // unicode
  "owner": *account schema
}

* See account schemas.

Issue comment schema

1
2
3
4
5
{
  "type": "issue_comment",
  "id": issue comment id,
  "issue": *issue schema
}

* See issue schema.

Commit comment schema

1
2
3
4
5
{
  "type": "commit_comment",
  "id": commit comment id, // int
  "commit": *commit schema
}

* See commit schema.

Pull request comment schema

1
2
3
4
5
{
  "type": "pullrequest_comment",
  "id": pullrequest comment id, // int
  "pullrequest": *pullrequest schema
}

* See pull request schema.

Build schemas

1
2
3
4
{
  "type": "build",
  "uuid": build uuid // unicode
}
1
2
3
4
5
6
7
{
  "type": "build",
  "key": build key, // unicode
  "repository": *repository schema,
  "commit": **commit schema,
  "refname": refname // unicode
}

* See repository schemas.

** See commit schema.

Commit schema

1
2
3
4
5
{
  "type": "commit",
  "repository": *repository schema,
  "hash": commit hash // unicode
}

* See repository schemas.

Snippet commit schema

1
2
3
4
5
{
  "type": "snippet_commit",
  "snippet": *snippet schema,
  "hash": commit hash // unicode
}

* See snippet schema.

Commit file schema

1
2
3
4
5
{
  "type": "commit_file",
  "commit": *commit schema,
  "path": path to file // unicode
}

* See commit schema.

Commit directory schema

1
2
3
4
5
{
  "type": "commit_directory",
  "commit": *commit schema,
  "path": path to directory // unicode
}

* See commit schema.


Rendered schemas

1
2
3
4
5
{
  "type": "rendered",
  "raw": raw content to render,
  ???
}

Error schema

1
2
3
4
5
6
7
8
9
10
{
  "type": "error",
  "error": {
    "message": error message,
    "id": error id,
    "data": error data,
    "fields": error fields,
    "detail": error detail
  }
}