Technology  ·  October 29, 2020

How GraphQL Helps Us Showcase CodeDay’s Impact

Tyler Menezes, CEO and Board Member

There’s always something exciting happening at CodeDay: last school year, almost 13,000 students worked on thousands of projects. On the other hand, like many non-profits without a budget for a web content team, our websites were infrequently updated with outdated information.

This year we set out to fix that by populating most of our websites dynamically with live data, photos, projects, etc. Here’s how we achieved that with a super-small team on a non-profit budget.

Starting with a Headless CMS

If you haven’t used a headless CMS, think “database with nice front-end”. If you’re on an extremely tight budget, setting us a headless CMS is the best place to start: it got us 80% of the way to our goal.

After evaluating several options, we chose Contentful because it was the most polished and supported GraphQL with a useful schema. (They also offer product donations for non-profits. )

Our Contentful instance stores things like:

  • Programs (e.g. CodeDay, CodeDay Labs, Big Data Challenge, etc)
  • Events (e.g. CodeDay seasons), including: dates, theme info/photos/videos/etc, kickoff video, and stats on attendance and outcomes.
  • Regions (i.e. where we host in-person events), including: local customization like collectable sticker SVGs, b-roll city photos/videos, and color preferences.
  • Sponsors, including: various sizes of blurbs, perks available to students, videos, an MP3 voice-over we can play at kick-offs, etc.
  • “Press Photos”, actually just nice photos, not specifically for the press.
  • Testimonials
  • FAQs

Like a database, we can cross-reference these types, and we use that extensively to give us flexibility in querying and displaying content later. For example, Testimonials are all tagged with Program, Region, and Event, so if you’re viewing a school registration page for CodeDay Bloomington-Normal, you’ll only see local quotes.

Building Our Own Services

Contentful got us about 80% of the way to the “live” feel we wanted, but to make things remarkably live, we needed custom GraphQL services. We’re currently running three:

Show Your Work

One of my favorite parts of our community is the #show-your-work Discord channel, where students post screenshots of their work-in-progress.

To bring this online, we built a bot which monitors #show-your-work. Whenever a staff member emoji-reacts to a post, it’s mirrored to our database and CDNs (Imgix/Mux), and the results are exposed in GraphQL.

Showcase

Our events use creative, project-based learning, and students have made over 10,000 fun projects over the years. Since 2016 volunteers have been cataloging them in a database called Showcase.

Showcase used to render these projects (and admin pages, etc) directly, but we upgraded it to a GraphQL API for viewing and managing projects.

Auth0

This summer we migrated our community accounts to Auth0 (from a system I wrote in 2014). We’ve now integrated all services with Auth0 (even Discord!), and we built a GraphQL front-end to the Auth0 API.

Bringing Things Together GraphQL

There’s an important reason why this post has focused on GraphQL over REST APIs: schema stitching. This feature lets us bring together information from multiple sources — sort of like a foreign key relation across APIs.

We first used Apollo Server to bring all these schemas into one place, so instead of requesting show-your-work.codeday.cloud for project screenshots, and then Auth0 for user information, we can make one request to graph.codeday.cloud for both, and have Apollo handle the backend requests and caching:

{
  showYourWork {
    messages (take: 10) {
      userId
      text
      imageUrl
    }
  }
  
  account {
    getUser( where: {
        username: "tylermenezes"
    }) {
      name
      picture
    }
  }
}

Here’s where it gets really cool. We use graphql-tools to make user information queryable as a subset of the post, automatically triggering a lookup to account.getUser with the post’s userId:

{
  showYourWork {
    messages (take: 10) {
      userId
      text
      imageUrl
      author {
        name
        picture
      }
    }
  }
}

Schema stitching makes the front-end code a lot cleaner, especially if you think about wanting to show something like all projects (showcase) with team member names and photos (Auth0) and region information (Contentful).

(GraphQL supports this more natively using something new called Federation, but it has some pretty major limitations.)

The Results

Our websites now have live stats…

A screenshot of CodeDay statistics displayed on a webpage.

…updated photos, WIP screenshots, and projects…

Screenshot showing photos and projects displayed on a webpage.

…and things like global sponsors and announcements are synchronized across all our sites.

A screenshot of sponsors on the Virtual CodeDay website.

Here are some more examples of cool things we’re now able to do:

  • Automatically generate kickoff slide-decks, including a kickoff video, theme information, and even an automatic reading of sponsors using MP3s we store with each sponsor in Contentful.
  • Send students info about other CS education opportunities in their community after they attend our events.
  • Automate judging, sponsor wrap-up emails, and more using showcase and account info.
  • Randomize our Discord server icon and banner image daily, so students have a chance to see themselves and their projects.

Thanks to Contentful and Auth0 for their generous product donations, and yaacovCR from graphql-tools for being friendly to GraphQL beginners and going way above-and-beyond to solve an issue I had with some major code changes.

If you liked this post, an easy way to support our work is to follow us on LinkedIn or Twitter. We often post volunteer and mentor opportunities.



Follow us on LinkedIn or Twitter