npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

dataloader-codegen

v0.4.4

Published

dataloader-codegen is an opinionated JavaScript library for automatically generating DataLoaders over a set of resources (e.g. HTTP endpoints)

Downloads

60

Readme

🤖 dataloader-codegen

npm Build Status

dataloader-codegen is an opinionated JavaScript library for automagically generating DataLoaders over a set of resources (e.g. HTTP endpoints), with a predictable interface, and maintains type safety.

Read more about the motivation behind this library in our recent blog post: https://engineeringblog.yelp.com/2020/04/open-sourcing-dataloader-codegen.html

header

Features:

  • 🚚 Supports Batched + Non Batched Resources
  • ✨ Predictable DataLoader Interfaces
  • 🐛 Error Handling
  • 🔒 Type Safety (Flow)
  • 🔧 Resource Middleware

Install

$ yarn add --dev dataloader-codegen

Why?

See: https://engineeringblog.yelp.com/2020/04/open-sourcing-dataloader-codegen.html

We believe the DataLoader layer should be (mostly) transparent when implementing a GraphQL server over a set of existing resources (e.g. HTTP API Endpoints).

When fetching data, GraphQL resolver authors should think in terms of the underlying resources that they're already familiar with, not an invented set of human defined DataLoaders.

With dataloader-codegen, we build a 1:1 mapping of resources to DataLoaders:

This makes it super easy to find the DataLoaders you want - there will be exactly 1 DataLoader available per resource, with a predictable name and interface.

This means reduced risk of making unnecessary HTTP requests.

If there were (accidentally!) multiple DataLoaders created for a single endpoint, we potentially lose out on batched requests to that resource.

By keeping the mapping of one DataLoader per resource, we reduce that risk and can make a more efficient set of HTTP requests to the underlying resource.

Usage

  1. Create dataloader-config.yaml to describe the shape and behaviour of your resources. (See the docs for detailed info.)

    Example

    resources:
        getPeople:
            docsLink: https://swapi.dev/documentation#people
            isBatchResource: true
            batchKey: people_ids
            newKey: person_id
        getPlanets:
            docsLink: https://swapi.dev/documentation#planets
            isBatchResource: true
            batchKey: planet_ids
            newKey: planet_id
        ...

    (Can be arbitrarily nested. See the swapi example for an example.)

  2. Call dataloader-codegen and pass in your config file:

    $ dataloader-codegen --config swapi.dataloader-config.yaml --output __codegen__/swapi-loaders.js

    See --help for more options.

  3. Import the generated loaders and use them in your resolver methods:

    import getLoaders from './__codegen__/swapi-loaders';
    
    // StarWarsAPI is a clientlib containing fetch calls to swapi.dev
    // getLoaders is the function that dataloader-codegen generates for us
    const swapiLoaders = getLoaders(StarWarsAPI);
    
    class Planet {
        constructor(id) {
            this.id = id;
        }
    
        async diameter() {
            const { diameter } = await swapiLoaders.getPlanets.load({ planet_id: this.id });
    
            return diameter;
        }
    }

    Check out the swapi example to see a working example of this.

Batch Resources

The DataLoader .load interface accepts a single key and returns a single value. For batch resources, we'll need to transform the DataLoader interface accordingly.

Example

Consider the following resource that returns information about users:

const getUserInfo = (args: {
    user_ids: Array<number>,
    locale: string,
    include_slow_fields?: boolean,
}): Promise<Array<UserInfo>> => fetch('/userInfo', args);

This is a batch resource that accepts a list of users (user_ids) and returns a list of corresponding user objects (Array<UserInfo>).

For the DataLoader version of this, we'll want to instead ask for a single user object at a time. This means we need to transform the interface in the following ways:

  1. Call .load with the same arguments, but switch "user_ids" to "user_id".

  2. Return a single UserInfo object from .load, instead of an array of UserInfo objects.

demo!

We can control this by specifying batchKey and newKey in the config to describe the relevant argument in the resource and DataLoader respectively.

The config for our getUserInfo would therefore look like this:

resources:
    getUserInfo:
        isBatchResource: true
        batchKey: user_ids
        newKey: user_id

See the full docs for more information on how to configure resources.

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Please make sure to update tests as appropriate.

Releasing

See PUBLISH.md

License

MIT