What is the reason databaseId field is deprecated?


#1

User.databaseId field is marked as deprecated in favour of the global “Relay” ID. As far as I can tell, the latter is just a hashed version of the former (base64(`04:User${databaseId}`)).

I’d like to use the databaseId (numeric ID) when storing a local reference of a GitHub user in my own RDBMs. Furthermore, databaseId is used to correlate data with the RESTful API.


#2

:wave: @gajus,

I’m going to try and answer this as best I can, piece by piece:

What is the reason databaseId field is deprecated?

In the world of GraphQL, databaseId represents an internal concern that we’d prefer not to expose. databaseIds are not used for query lookups, nor do we ever intend them to be (again, I’m referring just to the world of GraphQL :smile:). We’d prefer for our users to not depend on them always being present, because ideally, they won’t be. Instead, we’d like to make every GraphQL object accessible by its Relay ID or a vanity field like a Pull Request’s number.

But that gets us to reality :laughing:. Large parts of the GitHub application rely on databaseIds for references, and as you mentioned, it’s hugely beneficial in order to map the REST API to the GraphQL API with these IDs. That’s why they’re currently present. In the future we may take an inverse approach and expose the Relay IDs in the REST API.

I’d like to use the databaseId (numeric ID) when storing a local reference of a GitHub user in my own RDBMs.

I see no problem with that for now, but as the GraphQL API gets closer to production, I think it would be wise to also store the Relay ID as that field is a core concept to our GraphQL implementation and will never be deprecated.

I hope this helps answer your original question.

Cheers,
Brooks


#3

If databaseId is deprecated, what should we use instead? I need this value because it is what other third party services are using but cannot find another way to retrieve it.

Aside, I don’t know what a Relay ID is, where to find it or where it is documented.


#4

By “Relay” ID, I’m referring to the id field that is on most objects. Relay is the specification that we use for globally identifiable objects.


#5

Sure, but how can I derive the integer ID from the “relay” ID?


#6

They’re not related in a way where you can determine one based on the other. Taking a step back, I think that I missed your earlier comment:

I think it’s safe to use databaseId for this purpose. The main intent of deprecating databaseId is because it’s an identifier that we don’t plan to support in a post-REST API future, and we’d prefer that integrators rely on the new global ID fields. In this transition period where we support both the REST API and the GraphQL API, it may be a good idea to persist both IDs so that you can still use the databaseId for third party services, and id for your own internal representations to interact with the GraphQL API.


#7

@bswinnerton hi Brooks, I’m using the relay id from Issue, Organization, and Repository types. However, this field is not available on the type Actor/User when queried within an Issue author:

query {
  search(type: ISSUE, query: "id>0", first: 1) {
    edges {
      node {
        ... on Issue {
          author {
            id
            __typename
          }
        }
      }
    }
  }
}

Response:

{
  "data": null,
  "errors": [
    {
      "message": "Field 'id' doesn't exist on type 'Actor'",
      "locations": [
        {
          "line": 7,
          "column": 13
        }
      ]
    }
  ]
}

Response after removing id field:

{
  "data": {
    "search": {
      "edges": [
        {
          "node": {
            "author": {
              "__typename": "User"
            }
          }
        }
      ]
    }
  }
}

Any suggestions on how to identify the user in this case? I can think of:

  1. Make another call to get relay id by login. Though login could be renamed in the meantime.
  2. Parse id out of avatarUrl, which seems to be the only deterministic identifier at the moment. Can you confirm that’s the databaseId? Then:
    2.1. Make another call to get relay id by databaseId. Not sure if that’s possible?
    2.2. Use databaseId instead of relay id for data mapping. Any idea of when databaseId will be deprecated?

Finally, any idea of when relay id will be available under Issue.author as Actor User?


#9

Hi @wcamarao,

The return type of the Issue.author field is an Actor interface. You can always query fields directly on an interface (like login in this case), but in order to get more information about the underlying object behind an interface you can use what are called inline fragments. In order to get the id of a User, Organization, or Bot (the three types that implement the Actor interface), you can use this query:

query {
  search(type: ISSUE, query: "id>0", first: 1) {
    edges {
      node {
        ... on Issue {
          author {
            ... on User {
              id
            }
            
            ... on Organization {
              id
            }
            
            ... on Bot {
              id
            }
          }
        }
      }
    }
  }
}

#10

Fantastic @bswinnerton thanks for your help!


#11

Any updates on this topic now that databaseId is scheduled to be hard-removed from the API on 2018-07-01? Specifically, my app – built well before GraphQL was announced – relies on User.databaseId throughout and retrofitting to use the relay ID would be nigh impossible.

Any chance you will reconsider removing databaseId, at least from User which lacks any other vanity number? If not, I guess I’ll resort to scraping it out of the relay ID or the avatar URL, and hope that this remains viable in the future (since it’s obviously not officially supported).


#12

Hey @gajus !

We’ve just posted an announcement about these fields, let me know if you still have any questions or concerns :slight_smile: