🍋 Yuzu

Dashboard

Getting Started

The Yuzu Platform

Guides

Creating API Keys

Rate Limits

Usage with Apollo React/React Native

Recipes

Build a live-updating stock price badge

Show the latest exchange rates for your product

Streaming API

Subscription and Authorization

Available streams

Message reference

GraphQL API

Introduction to GraphQL

Making GraphQL Requests

Authorization

Pagination

Errors

Schema Reference

Recipes

Build a live-updating stock price badge

Yuzu can power UIs of any size: from huge sprawling webapps to drop-in UI components. In this example we'll focus on powering something on the small scale: a portable web component that renders a badge with live-updating stock prices, like this:

If you'd rather skip to the good part, we've created a GitHub Repo with our demo code.

Getting Started

Setup the project


Since we want this component to be fully portable and framework-agnostic, we'll be using Lit + Typescript to create a native Web Component. This guide assumes you have the following tools installed:

  • Yarn
  • Node.js

To get started, we'll use yarn to create a project for us.

Terminal
$
$
$
yarn create vite yuzu-stock-price-badge --template lit-ts
cd yuzu-stock-price-badge
yarn install
Copy

The code above creates a new project folder using Vite as the build tool, then moves into the directory and installs dependencies.

Once we're in our new project and have run a fresh yarn install, let's do a few things.

  1. Vite has created one component for us at src/my-element.ts. Let's rename it to yuzu-price-badge.ts.
  2. In src/yuzu-price-badge.ts, let's replace all occurences of my-element with yuzu-price-badge.
  3. In package.json, index.html, and vite.config.ts, go ahead and do the same thing, replacing all usages of my-element with yuzu-price-badge.
  4. Run yarn build and make sure everything looks ok!

If that sounds like a lot of work, you can just run these commands in your terminal instead:

Terminal
$
$



$
mv src/my-element.ts src/yuzu-price-badge.ts
sed -i '' 's/my-element/yuzu-price-badge/g' vite.config.ts \
  src/yuzu-price-badge.ts \
  package.json \
  index.html
sed -i '' 's/MyElement/YuzuPriceBadge/g' src/yuzu-price-badge.ts
Copy

Next, let's clean out all the boilerplate from src/yuzu-stock-price-badge.ts. The file should look about this this when you're done:

src/yuzu-price-badge.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import { html, css, LitElement } from 'lit'
import { customElement, property, state } from 'lit/decorators.js'

/**
 * Yuzu stock price badge
 */
@customElement('yuzu-price-badge')
export class YuzuPriceBadge extends LitElement {
  static styles = css`
    :host {
    }
  `

  render() {
    return html``
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'yuzu-price-badge': YuzuPriceBadge
  }
}
Copy

Ok, now that we're at a good baseline, let's add some properties to our new component, just above our render method:

src/yuzu-price-badge.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
 * Your Yuzu API key, exposed in HTML as "api-key"
 */
@property({ type: String, attribute: "api-key" })
apiKey = "";

/**
 * The symbol to render
 * E.g. AAPL, MSFT, BRK.A
 */
@property({ type: String })
symbol = "";

/**
 * Hold the last price of our stock
 */
@state()
private lastPrice: number = 0;
Copy

Our two new properties, apiKey and symbol will be exposed in HTML to change what's rendered in this badge. The third property, lastPrice is a bit of internal state that will hold the last known price of our stock. Let's go to index.html and update our component.

index.html
1
2
3
4
<body>
  <yuzu-price-badge api-key="demo-KTq7CmTXwGr" symbol="BYND">
  </yuzu-price-badge>
</body>
Copy

Fetching initial data


Great! Now, we need to fetch the last price of our stock when the component loads. We can override the connectedCallback function from LitElement to do that. Let's put our connectedCallback between our new properties and the render method.

src/yuzu-price-badge.ts
1
2
3
async connectedCallback() {
  super.connectedCallback();
}
Copy

Next, we're going to do two things:

  1. Make a GraphQL request to grab the last price of the stock.
  2. Subscribe to the live price stream for our stock, and update our internal state when the price changes.

Because Yuzu's streaming APIs only returns data on stocks during market hours, it's good practice to use the GraphQL API to fetch any data you need to render your UI, and then subscribe to subsequent updates.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
!src/yuzu-price-badge.ts:typescript
async connectedCallback() {
  super.connectedCallback();

  // Visit https://graph.yuzu.dev/graphql to see docs on the whole graph
  const query = `query {
    securities(input: { symbols: ["${this.symbol}"] }) {
      lastTrade {
        price
      }
    }
  }`

  const graphQlResult = await fetch("https://graph.yuzu.dev/graphql", {
    method: "POST",
    body: JSON.stringify({
      query
    }),
    headers: {
      'Authorization': `Bearer ${this.apiKey}`,
      'Content-Type': "application/json",
    }
  });
  const { data } = await graphQlResult.json();

  this.lastPrice = parseFloat(data.securities[0].lastTrade.price);
}

Great! Here's a quick breakdown of what's happening above:

  1. Construct the body of our GraphQL query, requesting securities matching our symbol, and on that object, the price field of that security's last trade.
  2. Using the Fetch API to make the request, parsing the result, and assigning the value to this.lastPrice.

And we're done!


Recipes

Show the latest exchange rates for your product