DEV Community

Cover image for Automate Your Portfolio with the GitHub GraphQL API
Josh Ellis
Josh Ellis

Posted on • Updated on

Automate Your Portfolio with the GitHub GraphQL API

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
    }
  }
Enter fullscreen mode Exit fullscreen mode

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
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
Enter fullscreen mode Exit fullscreen mode

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
      ) {
        ...
      }
    }
Enter fullscreen mode Exit fullscreen mode

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))
}, [])
Enter fullscreen mode Exit fullscreen mode

What About You?

What ways are you using APIs on your portfolio? I'd love to see what you've done!

Discussion (21)

Collapse
imjoshellis profile image
Josh Ellis Author

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

Collapse
karthiknayak98 profile image
KarthikNayak

Yes

Collapse
imjoshellis profile image
Josh Ellis Author

Followup posted: dev.to/imjoshellis/how-to-build-an...

Hope it's helpful!

Collapse
arcbjorn profile image
Arc

Yes! There are still not so many graphql tutorials, compared to REST. So this will be highly appreciated πŸ‘Œ

Collapse
imjoshellis profile image
Josh Ellis Author

Followup posted: dev.to/imjoshellis/how-to-build-an...

Hope it's helpful!

Collapse
imjoshellis profile image
Josh Ellis Author

Ok I’ll try to put something out in the next week about how to set up Apollo and process the responses!

Collapse
siddm22 profile image
Siddhant Misra

Would love to see an implementation of this. Looking forward to it.

Collapse
imjoshellis profile image
Josh Ellis Author

Followup posted: dev.to/imjoshellis/how-to-build-an...

Hope it's helpful!

Collapse
imjoshellis profile image
Josh Ellis Author

I'll follow up with a from-init walkthrough of how to use this in React sometime next week!

Collapse
michaelcurrin profile image
Michael • Edited

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.

Collapse
htshah profile image
Het Shah

That’s exactly what I am implementing for my portfolio.

Collapse
imjoshellis profile image
Josh Ellis Author

Is your site live? I’d love to see it

Collapse
htshah profile image
Het Shah

I am still working on it. Will definitely write a blog post about it.

Collapse
teslaji profile image
Kuldeep Bhatt

@imjoshellis your site is absolutely well designed and functional. Thanks for the inspiration.

Collapse
imjoshellis profile image
Josh Ellis Author

Thank you!

Collapse
satyam1203 profile image
Satyam Lachhwani

Are you talking about something like this:
resume-github.vercel.app

Collapse
imjoshellis profile image
Josh Ellis Author

Yeah, that's pretty similar to what I have in a way. You can see my site here: imjoshellis.com

Collapse
satyam1203 profile image
Satyam Lachhwani

It's absolutely great...

Thread Thread
imjoshellis profile image
Josh Ellis Author

Thanks!

Collapse
dmahely profile image
Doaa Mahely

Very efficient πŸ‘ŒπŸ½

Collapse
imjoshellis profile image
Josh Ellis Author

Work smarter, not harder, right?