This is an overview of how I'm currently using GitHub's API to automate my website. I'm transitioning from graduating bootcamp to looking for a job, and I wanted to get the portfolio up and running as quickly as possible.
The Idea
Build a portfolio site that showcases up-to-date project information without requiring too much direct maintenance.
The Reason
- Fast: Since I come from a design background, I knew I would overthink it and waste time if I built a static site
- Efficient: I'm already trying to make my GitHub look as good as possible, why do the work twice?
- Strategic: I wanted my website to showcase my ability to work with external APIs.
- Practical: I believe most decision-makers will be going to my site just to see my projects, whether on GitHub or live, so making that easy for them is key.
Planning the data
The first thing I did was decide what kind of information I wanted to put on my website. The good news is GitHub exposes virtually everything with their API.
I settled on the following:
- Profile info
- Three featured repos (my top three pinned repos)
- Three most recent repos (only public, non-forks)
For the profile info, I'll be grabbing almost everything available:
- Name
- Avatar
- Bio
- Status
- Status emoji
- Location
- Work Status
- Education
For each repo, I settled on this data:
- Tags
- Title
- Description
- Image (via the OpenGraph image in settings)
- Link to repo
- Link to demo (if available)
- Most recent commit message/time/branch
Using the GitHub GraphQL API
If you haven't worked with GraphQL before, I highly recommend looking into some other tutorials since I won't be covering the basics here.
Essentially, the idea is when you make a Query (similar to a GET request), you can tell the server what parts of the data you want.
This means we can make very specific calls to the API that give us the most relevant information.
Let's start simple with my profile info query. Note: To actually make the queries and process the response, I'll be using Apollo.
query GetAbout {
viewer {
id
name
bio
avatarUrl
location
url
status {
emojiHTML
message
}
company
}
}
The response will be an object shaped just like the query, which makes it easy to work with. If I want my bio data, for example, I would just store the response in a variable using Apollo and call response.viewer.bio
.
The viewer
key refers to me since I'm using an API key to make authenticated queries.
My featured repository call is a bit more complicated:
query GetFeaturedRepos {
viewer {
id
pinnedItems(first: 3) {
edges {
node {
... on Repository {
name
description
homepageUrl
pushedAt
url
openGraphImageUrl
usesCustomOpenGraphImage
refs(refPrefix: "refs/heads/", last: 3) {
nodes {
name
target {
... on Commit {
history {
totalCount
}
messageHeadline
pushedDate
}
}
}
}
repositoryTopics(first: 100) {
edges {
node {
topic {
name
}
}
}
}
}
}
}
}
}
}
The first thing is I only want three of my pinned Repositories, so I use pinnedItems(first: 3)
to limit the response. Then, GitHub uses a node/edge format, which I honestly still don't fully understand.
The gist of it is pinnedItems
will return a list of edges
which each have a node
. Then on the node
, you have to grab the repository with ... on Repository
, then you can access the repository fields.
You also do a similar thing for commits if you want to get that info.
Honestly, it took a ton of trial/error, Google, and playing with the explorer tool to get things like ... on Repository
working properly.
My other call to get my most recent pushed repositories looks almost identical to the above since I want the same info about each repository. The main difference is the filter:
viewer {
id
repositories(
orderBy: { field: PUSHED_AT, direction: ASC }
last: 3
privacy: PUBLIC
isFork: false
) {
...
}
}
In this case, I'm calling for all my repositories, ordering them by recent pushes, filtering out any that are private or forks, then grabbing three.
Wrap Up
And that's it! Once you have the data, it's simply a matter of creating TSX to display it, along with some conditionals and fallbacks in case the data doesn't exist.
Like I said at the start, this is just an overview, not a comprehensive tutorial... If you want to do something similar, here are helpful resources to get you going:
Resources
- Get Started with Apollo
- GitHub GraphQL API docs
- Test queries in your browser with the GitHub GraphQL explorer
- My portfolio on GitHub
- My portfolio website
Bonus: Using the Dev.to API
I also set up a simple call to the Dev.to API to grab a list of my articles. Here's what that looks like in my BlogPosts React component:
const [state, setState] = useState(undefined)
const DEVTO_API_URL = 'https://dev.to/api/'
useEffect(() => {
fetch(DEVTO_API_URL + 'articles?username=imjoshellis', {})
.then(res => res.json())
.then((json: DevToArticles) => setState(json))
}, [])
What About You?
What ways are you using APIs on your portfolio? I'd love to see what you've done!
Top comments (21)
Are you interested in how to actually implement this? Let me know. I might do a follow-up!
Yes
Followup posted: dev.to/imjoshellis/how-to-build-an...
Hope it's helpful!
Yes! There are still not so many graphql tutorials, compared to REST. So this will be highly appreciated 👌
Followup posted: dev.to/imjoshellis/how-to-build-an...
Hope it's helpful!
Ok I’ll try to put something out in the next week about how to set up Apollo and process the responses!
Would love to see an implementation of this. Looking forward to it.
Followup posted: dev.to/imjoshellis/how-to-build-an...
Hope it's helpful!
I'll follow up with a from-init walkthrough of how to use this in React sometime next week!
Thanks for sharing. I'll see if I can use that for my queries.
I have a portfolio using GraphQL data. I did it specifically to get the topic data so I can have my
#jekyll
projects together for example.github.com/MichaelCurrin/my-github...
There's a link to the site there.
I use a token on Netlify and Ruby to build the static site. Check my .gql file in
_plugins
if you are interested in the query.That’s exactly what I am implementing for my portfolio.
Is your site live? I’d love to see it
I am still working on it. Will definitely write a blog post about it.
@imjoshellis your site is absolutely well designed and functional. Thanks for the inspiration.
Thank you!
Are you talking about something like this:
resume-github.vercel.app
Yeah, that's pretty similar to what I have in a way. You can see my site here: imjoshellis.com
It's absolutely great...
Thanks!
Very efficient 👌🏽
Work smarter, not harder, right?