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 🙏

© 2026 – Pkg Stats / Ryan Hefner

gqly

v1.1.0

Published

Bridge REST APIs and GraphQL by mapping existing controllers

Downloads

4

Readme

GQLY

GQLY Cover

Zero-Boilerplate GraphQL for Express & NestJS

gqly is a powerful library that instantly turns your existing REST controllers into a GraphQL API without writing schemas, resolvers, or DTOs manually. It inspects your configuration and automatically wires everything up, mapping GraphQL arguments directly to req.body and req.params.

Features

  • 🚀 Zero Boilerplate: No manual schema or resolver definition required.
  • 🔄 Reuse REST Controllers: Use your existing Express/NestJS controllers as-is.
  • 🔌 Framework Agnostic: Works seamlessly with both Express and NestJS.
  • 📄 YAML Configuration: Define your API structure in a simple YAML file.
  • 🛡️ Automatic Argument Mapping: GraphQL arguments are automatically mapped to req.body and req.params.
  • 🎮 Built-in Playground: Includes GraphQL Playground for easy testing.

Installation

npm install gqly
# or
yarn add gqly

Configuration

Create a gqly.config.yaml file in your project. This file defines your GraphQL schema and maps it to your controllers.

Path Specifications

[!IMPORTANT] Controller Paths in YAML Config: Use relative filenames only (e.g., userController.js#getUser). These are resolved relative to the controllersPath option you provide when initializing gqly.

[!IMPORTANT] API Options Paths: Use absolute paths with path.join(__dirname, ...) for configPath and controllersPath options.

Example Configuration

queries:
  getUser:
    description: "Fetch user by ID"
    controller: "userController.js#getUser" # ✅ Relative filename only
    input:
      type: object
      properties:
        id: { type: string }
      required: [id]
    output:
      type: object
      properties:
        id: { type: integer }
        name: { type: string }
        email: { type: string }
    http:
      paramMapping:
        id: id # Maps GraphQL 'id' argument to req.params.id

  getAllUsers:
    description: "Fetch all users"
    controller: "userController.js#getAllUsers" # ✅ Same file, different function
    output:
      type: array
      items:
        type: object
        properties:
          id: { type: integer }
          name: { type: string }
          email: { type: string }

mutations:
  createUser:
    description: "Create new user"
    controller: "userController.js#createUser"
    input:
      type: object
      properties:
        name: { type: string }
        email: { type: string }
      required: [name, email]
    output:
      type: object
      properties:
        id: { type: integer }
        name: { type: string }
    http: {} # Arguments are automatically mapped to req.body by default

  login:
    description: "Login user"
    controller: "authController.js#login" # ✅ Different controller file
    input:
      type: object
      properties:
        email: { type: string }
        password: { type: string }
      required: [email, password]
    output:
      type: object
      properties:
        token: { type: string }
        user:
          type: object
          properties:
            id: { type: integer }
            name: { type: string }
    http: {}

Configuration Options

Operation Fields

  • queries/mutations: Define your GraphQL operations.
  • controller: Relative filename and function name, separated by # (e.g., userController.js#getUser).
    • Format: <filename>#<exportedFunction>
    • Path is resolved relative to the controllersPath option
    • ✅ Correct: "userController.js#getUser"
    • ❌ Wrong: "./controllers/userController.js#getUser" (don't include directory)
    • ❌ Wrong: "/absolute/path/userController.js#getUser" (don't use absolute paths)
  • description: Human-readable description of the operation.
  • input: JSON Schema definition for the input arguments (optional for queries without arguments).
  • output: JSON Schema definition for the return type.
  • http: HTTP-specific configuration.

HTTP Configuration

  • http.paramMapping: Map GraphQL arguments to req.params.
    • Example: { id: id } maps the GraphQL id argument to req.params.id
    • If omitted, all arguments are mapped to req.body by default.

Usage

Controller Implementation

gqly is designed to work with standard Express-style controllers. Your controllers should expect req and res objects.

// userController.js
exports.getUser = async (req, res) => {
    const { id } = req.params; // Mapped from http.paramMapping
    // ... logic to fetch user
    res.json(user);
};

exports.createUser = async (req, res) => {
    const { name, email } = req.body; // Mapped from input arguments
    // ... logic to create user
    res.json(newUser);
};

Express Integration

const express = require('express');
const { attachGraphQL } = require('gqly');
const path = require('path');

const app = express();
app.use(express.json());

// ... your other middleware and routes

attachGraphQL(app, path.join(__dirname, 'gqly.config.yaml'), {
    controllersPath: path.join(__dirname, 'controllers'), // Directory where controllers are located
    route: '/graphql', // Endpoint for GraphQL
    playground: true // Enable GraphQL Playground
});

app.listen(3000, () => {
    console.log('Server running on http://localhost:3000');
    console.log('GraphQL endpoint: http://localhost:3000/graphql');
});

NestJS Integration

Import GqlyModule in your root AppModule.

import { Module } from '@nestjs/common';
import { GqlyModule } from 'gqly/nestjs';
import * as path from 'path';

@Module({
    imports: [
        GqlyModule.forRoot({
            configPath: path.join(__dirname, '../gqly.config.yaml'),
            controllersPath: path.join(__dirname, '../controllers'),
            route: '/graphql',
            playground: true,
        }),
    ],
})
export class AppModule { }

API Reference

attachGraphQL(app, configPath, options)

Attaches GraphQL endpoint to your Express application.

Parameters:

  • app (Express Application): The Express application instance.
  • configPath (string): Absolute path to the gqly.config.yaml file.
    • ✅ Use: path.join(__dirname, 'gqly.config.yaml')
    • ❌ Avoid: './gqly.config.yaml' (relative paths may fail)
  • options (object):
    • controllersPath (string): Absolute path to the directory containing your controllers.
      • ✅ Use: path.join(__dirname, 'controllers')
      • ❌ Avoid: './controllers' (relative paths may fail)
    • route (string, optional): The URL path for the GraphQL endpoint. Default: '/graphql'
    • playground (boolean, optional): Enable/disable GraphQL Playground. Default: true

Example:

const path = require('path');
const { attachGraphQL } = require('gqly');

attachGraphQL(app, path.join(__dirname, 'gqly.config.yaml'), {
    controllersPath: path.join(__dirname, 'controllers'),
    route: '/graphql',
    playground: true
});

GqlyModule.forRoot(options) (NestJS)

Creates a dynamic NestJS module for GraphQL integration.

Parameters:

  • options (object):
    • configPath (string): Absolute path to the gqly.config.yaml file.
      • ✅ Use: path.join(__dirname, '../gqly.config.yaml')
      • Note: In NestJS, __dirname points to the dist folder after compilation
    • controllersPath (string): Absolute path to the directory containing your controllers.
      • ✅ Use: path.join(__dirname, '../controllers')
    • route (string, optional): The URL path for the GraphQL endpoint. Default: '/graphql'
    • playground (boolean, optional): Enable/disable GraphQL Playground. Default: true

Example:

import { Module } from '@nestjs/common';
import { GqlyModule } from 'gqly/nestjs';
import * as path from 'path';

@Module({
    imports: [
        GqlyModule.forRoot({
            configPath: path.join(__dirname, '../gqly.config.yaml'),
            controllersPath: path.join(__dirname, '../controllers'),
            route: '/graphql',
            playground: true,
        }),
    ],
})
export class AppModule { }

Path Resolution Summary

| Context | Path Type | Example | |---------|-----------|---------| | YAML Config - controller field | Relative filename only | "userController.js#getUser" | | Express - configPath | Absolute path | path.join(__dirname, 'gqly.config.yaml') | | Express - controllersPath | Absolute path | path.join(__dirname, 'controllers') | | NestJS - configPath | Absolute path | path.join(__dirname, '../gqly.config.yaml') | | NestJS - controllersPath | Absolute path | path.join(__dirname, '../controllers') |

License

ISC