loading...
Cover image for Automate Your Portfolio with the GitHub GraphQL API

Automate Your Portfolio with the GitHub GraphQL API

imjoshellis profile image Josh Ellis Updated on ・4 min read

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

  1. Fast: Since I come from a design background, I knew I would overthink it and waste time if I built a static site
  2. Efficient: I'm already trying to make my GitHub look as good as possible, why do the work twice?
  3. Strategic: I wanted my website to showcase my ability to work with external APIs.
  4. 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

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!

Posted on by:

imjoshellis profile

Josh Ellis

@imjoshellis

he/him β€’ Crafting products that simplify the human experience. I'm passionate about innovative tech in productivity πŸ“‹οΈ, mental health πŸ§˜β€β™‚οΈοΈ, and travel πŸ•οΈ.

Discussion

pic
Editor guide
 

Are you interested in how to actually implement this? Let me know. I might do a follow-up!

 
 

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.

img

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...

 

Very efficient πŸ‘ŒπŸ½

 

Work smarter, not harder, right?