• Docs
  • Pricing
  • Support
  • Blog
  • Login

›On the frontend

Intro

  • What's OneGraph?
  • How does it work?
  • Creating your first app
  • Making your first query
  • OneGraphiQL
  • Authentication & Security Overview
  • Custom Google Auth

On the frontend

  • Using with Apollo
  • Log in to services
  • Example with create-react-app

External Authentication

  • What are JWTs?
  • AuthGuardian
  • Securing your Apollo server
  • Securing your Hasura API
  • Securing your Netlify site
  • Securing your express.js app
  • Advanced JWT customization with webhooks

Subscriptions

  • Subscriptions
  • Webhook-based subscriptions
  • Websocket-based subscriptions
  • Salesforce subscriptions
  • GitHub subscriptions
  • Gmail Subscriptions

Advanced

  • Persisted Queries
  • Mailchimp Signup with Persisted Queries

Example OneGraph App: YouTube Captions

We'll create an app that searches YouTube captions to demonstrate how to create a fully client-side app with OneGraph.

You can dive in and view the code on GitHub or continue reading to see how to create it from scratch.

Creating the app

First, make sure you have node.js installed.

$ node -version v10.6.0

Install create-create-app:

npm install -g create-react-app

Create a new app:

create-react-app youtube-captions
cd youtube-captions
npm start

You should see a blank page like below:

Empty create-react-app

Let's add a sign in button so that we can make requests to YouTube on behalf of the user.

We'll install all of the npm packages we need:

 npm install apollo-boost react-apollo@beta graphql \
  onegraph-auth onegraph-apollo-client --save

We'll use onegraph-auth to check if we're logged in to YouTube. If we're not logged in, we'll display a login button. If we are logged in, we'll just display a short "You're logged in" message.

You'll need an app id for this. Head over to the dashboard to get one.

Replace src/App.js with the following:

import OneGraphAuth from 'onegraph-auth';

import React, {Component} from 'react';
import logo from './logo.svg';
import './App.css';

const APP_ID = YOUR_APP_ID;

class App extends Component {
  state = {
    isLoggedIn: false,
  };

  constructor(props) {
    super(props);
    this._oneGraphAuth = new OneGraphAuth({
      appId: APP_ID,
    });
  }

  _authWithYoutube = async () => {
    await this._oneGraphAuth.login('youtube');
    const isLoggedIn = await this._oneGraphAuth.isLoggedIn('youtube');
    this.setState({isLoggedIn: isLoggedIn});
  };

  componentDidMount() {
    this._oneGraphAuth
      .isLoggedIn('youtube')
      .then((isLoggedIn) => this.setState({isLoggedIn}));
  }

  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">YouTube Captions</h1>
        </header>
        <p className="App-intro">
          {this.state.isLoggedIn ? (
            <span>You are logged in with YouTube</span>
          ) : (
            <button style={{fontSize: 18}} onClick={this._authWithYoutube}>
              Login with YouTube
            </button>
          )}
        </p>
      </div>
    );
  }
}

export default App;

You should see a login button like below:

Login button

Click the button to authenticate with YouTube and you'll see the message "You are logged in with YouTube".

Now that we can make requests to YouTube, we're ready to display the captions for a video.

We'll add onegraph-apollo-client, hook it up to our React app with an ApolloProvider, and write a query that list captions for a hardcoded video:

import {gql} from 'apollo-boost';
import {ApolloProvider, Query} from 'react-apollo';
import OneGraphApolloClient from 'onegraph-apollo-client';
import OneGraphAuth from 'onegraph-auth';

import React, {Component} from 'react';
import logo from './logo.svg';
import './App.css';

const APP_ID = YOUR_APP_ID;

const GET_VIDEO = gql`
  query VideoWithCaptionsQuery($videoId: String!) {
    youTube {
      video(id: $videoId) {
        id
        snippet {
          title
        }
        captions {
          items {
            snippet {
              language
              status
            }
            body
          }
        }
      }
    }
  }
`;

class App extends Component {
  state = {
    isLoggedIn: false,
  };

  constructor(props) {
    super(props);
    this._oneGraphAuth = new OneGraphAuth({
      appId: APP_ID,
    });
    this._oneGraphClient = new OneGraphApolloClient({
      oneGraphAuth: this._oneGraphAuth,
    });
  }

  _authWithYoutube = async () => {
    await this._oneGraphAuth.login('youtube');
    const isLoggedIn = await this._oneGraphAuth.isLoggedIn('youtube');
    this.setState({isLoggedIn: isLoggedIn});
  };

  componentDidMount() {
    this._oneGraphAuth
      .isLoggedIn('youtube')
      .then((isLoggedIn) => this.setState({isLoggedIn}));
  }

  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">YouTube Captions</h1>
        </header>
        <div className="App-intro">
          {this.state.isLoggedIn ? (
            <ApolloProvider client={this._oneGraphClient}>
              <Query query={GET_VIDEO} variables={{videoId: 't6CRZ-iG39g'}}>
                {({loading, error, data}) => {
                  if (loading) return <div>Loading video...</div>;
                  if (error)
                    return (
                      <div>Uh oh, something went wrong: {error.message}</div>
                    );
                  if (!data.youTube.video) {
                    return <div>Could not find a video with that id.</div>;
                  }
                  const caption = data.youTube.video.captions.items.find(
                    (caption) =>
                      caption.snippet.status === 'serving' &&
                      caption.snippet.language === 'en',
                  );
                  return <pre>{caption.body}</pre>;
                }}
              </Query>
            </ApolloProvider>
          ) : (
            <button style={{fontSize: 18}} onClick={this._authWithYoutube}>
              Login with YouTube
            </button>
          )}
        </div>
      </div>
    );
  }
}

export default App;

Now you should see a list of all of the captions.

We'll stop here, but you can view the GitHub repo to see a version that's a bit more polished.

We created an app that

  1. logs a user into YouTube
  2. makes queries to YouTube on their behalf
  3. displays captions for a video.

We did it all without needing to view the YouTube API docs or set up our own server.

← Log in to servicesWhat are JWTs? →
Links
OneGraph Overview Example projectsOneGraphiQL Explorer
Support
Live chat on Spectrum> TwitterBlog
More
Terms of ServicePrivacy Policy
Copyright © 2021 OneGraph