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

granate

v1.10.0

Published

Granate container for annotated GraphQL

Downloads

8

Readme

granate

npm version Build Status Coverage Status

Granate container for annotated GraphQL

Introduction

GraphQL is an amazing technology that allows to build application APIs in a much better way than by implementing REST services. On top of this, GraphQL can be defined using a textual representation (schema language) which offers a lot of really useful possibilities. Granate leverages these possibilities.

Usage

To understand better how to use granate, please have a look at the examples in granate-showcase

Installation

In order to use granate from the CLI, install granate-cli with the following command:

> npm i -g granate-cli

If you prefer to use granate as an API, install granate and graphql (peer dependency of granate) in your application with the following command:

> npm i granate graphql --save

Where does granate come from? (TL;DR)

Imagine that you want to implement a Todo application and you have drafted a GraphQL schema which looks as follows:

# Domain entity which represents a Todo object
type Todo {
    id: ID!
    title: String!
    completed: Boolean!
}

# Query model for Todos
type Query {
    # Returns the collection of Todos filtered by completed status (optional)
    todos(completed: Boolean): [Todo]
}

# Mutations for Todos
type Mutation {
    # Adds an uncompleted Todo with the given description
    addTodo(title: String!): Todo!
    # Removes a Todo by id
    removeTodo(id: ID!): Todo!
    # Toggles the completed state of a Todo by id
    toggleTodo(id: ID!): Todo!
}

As of [email protected], by using the buildSchema() and graphql() functions together with an object like the one below as rootValue, it is then possible to execute GraphQL queries and mutations against the object as if it were a full-fledged GraphQL endpoint.

export class Todos {
    constructor() {
        this.nextId = Date.now();
        this.todos = [];
    }

    todos({completed}) {
        return this.todos.filter(completedFilter);

        function completedFilter(todo) {
            return completed === undefined ? todo : todo.completed === completed;
        }
    }

    addTodo({title}) {
        const todo = {
            id: String(this.nextId++),
            title,
            completed: false
        };
        this.todos.push(todo);

        return todo;
    }

    removeTodo({id}) {
        const todo = this.todos.filter(todo => todo.id === id)[0];
        todos.splice(this.todos.indexOf(todo), 1);

        return todo;
    }

    toggleTodo({id}) {
        const todo = this.todos.filter(todo => todo.id === id)[0];
        todo.completed = !todo.completed;

        return todo;
    }
}

Then you can use this as:

import { buildSchema } from 'graphql';
import { Todos } from './todos';

const schemaText = `
# Domain entity which represents a Todo object
type Todo {
... content skipped
`;
const query = `
    { 
        todos {
            title
            completed
        }
    }`;
const todos = new Todos();

graphql(buildSchema(schemaText), query, todos).then(result => console.log(result)); // prints the query result

And if you want to make this API available through HTTP:

import express from 'express';
import graphqlHTTP from 'express-graphql';
import { buildSchema } from 'graphql';
import { Todos } from './todos';

const PORT = 4000;
const schemaText = `
# Domain entity which represents a Todo object
type Todo {
... content skipped
`;
const todos = new Todos();
const graphqlHTTPConfig = createGraphQLHTTPConfig(buildSchema(schemaText), todos);

express()
    .use('/graphql', graphqlHTTP(graphqlHTTPConfig))
    .listen(PORT, () => console.log(`Listening on port: '${PORT}'...`));

function createGraphQLHTTPConfig(schema, rootValue) {
    return {
        schema,
        rootValue,
        graphiql: true
    };
}

Wouldn't it be cool if we could avoid defining the rootValue implementation and use instead mock data like the one generated by casual or faker.js? This would allow to mock an API just by using a GraphQL schema text file. Well, we easily can if we use the package graphql-tools as explained in Mocking your server with just one line of code.

  • But, wouldn't it be better if we could start with a schema file and default mock data and incrementally refine the mock data or even the implementation to use as rootValue?
  • And what if we could use mock data where the root value provides no implementation?
  • Couldn't we eventually use a legacy REST API to implement part of the schema?
  • And if we could reuse not only existing REST APIs but also GraphQL endpoints?
  • Even better, what if I could just install a library and do all this from the CLI without writing any code?

###... enter Granate!