Querying for Commits on Master using Github Graphql API v4
I was pretty excited to see that the new Github API (v4) used Graphql. I wanted to retrieve the last x commits from master for a project I was working on. Should be easy right? After a bunch of time wasted on GitHub’s GraphQL Explorer I came up with the following which didn’t really solve my issue:
query{repository(owner: "typelevel", name: "cats") {
defaultBranchRef {
name
prefixassociatedPullRequests(states: [MERGED], last: 5) {
edges {
node {
title
}
}
}
}
} }
It was limited to PRs and didn’t really seem like a nice solution.
I then asked this question on Stackoverflow.
Meanwhile while rummaging around the Github platform Forum I came across this post that gave me some clues:
{repository(owner: "golang", name: "go") {
defaultBranchRef {
target {... on Commit {
history(first: 10) {
pageInfo {
hasNextPage
endCursor
}
edges {
node {
oid
messageHeadline
}
}
}
}
}
}
} }
So I modified the above to suit my needs and came up with this query that returned the most recent commits on master:
query {repository(owner: "typelevel", name: "cats") {
ref(qualifiedName: "master") {
target {... on Commit {
history(first: 10) {
pageInfo {
hasNextPage
endCursor
}
edges {
node {
oid
messageHeadline
}
}
}
}
}
}
} }
Graphql was supposed to make understanding the structure of an API much easier with automatically generated documentation and tools like Graphiql. What still seems to be missing is how to sort through interfaces and their implementations easily to figure out what type of objects are returned from query.
For example in the Github API, the Repository object implements the following other interfaces:
- Node
- ProjectOwner
- Subscribable
- Starrable
- UniformResourceLocatable
- RepositoryInfo
And if we just look at the Node interface, we see that it has the following implementations:
- Organization
- Project
- ProjectColumn
- ProjectCard
- Issue
- User
- Repository
- CommitComment
- Reaction
- Commit
- Status
- StatusContext
- Tree
- Ref
- PullRequest
- Label
- IssueComment
- PullRequestCommit
- Milestone
- ReviewRequest
- PullRequestReview
- PullRequestReviewComment
- CommitCommentThread
- PullRequestReviewThread
- ClosedEvent
- ReopenedEvent
- SubscribedEvent
- UnsubscribedEvent
- MergedEvent
- ReferencedEvent
- CrossReferencedEvent
- AssignedEvent
- UnassignedEvent
- LabeledEvent
- UnlabeledEvent
- MilestonedEvent
- DemilestonedEvent
- RenamedTitleEvent
- LockedEvent
- UnlockedEvent
- DeployedEvent
- Deployment
- DeploymentStatus
- HeadRefDeletedEvent
- HeadRefRestoredEvent
- HeadRefForcePushedEvent
- BaseRefForcePushedEvent
- ReviewRequestedEvent
- ReviewRequestRemovedEvent
- ReviewDismissedEvent
- Language
- ProtectedBranch
- PushAllowance
- Team
- ReviewDismissalAllowance
- Release
- ReleaseAsset
- RepositoryTopic
- Topic
- Gist
- GistComment
- OrganizationIdentityProvider
- ExternalIdentity
- Blob
- Bot
- RepositoryInvitation
- Tag
- AddedToProjectEvent
- BaseRefChangedEvent
- CommentDeletedEvent
- ConvertedNoteToIssueEvent
- MentionedEvent
- MovedColumnsInProjectEvent
That’s a few too many options to manually sort through.
The example documentation has a very simple example with a few implementations of an interface:
{search(text: "an") {
... on Human {
name
height
}... on Droid {
name
primaryFunction
}... on Starship {
name
length
}
} }
While this seems manageable it can easily get out of hand as per the Github API.
So even though Graphql does provide automatic documentation, if your domain model is complex enough, you probably still need to provide the users of your API some documentation on how everything hangs together.