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

fast-qjs

v0.0.7

Published

**qjs**是一个基于**fastify**实现的轻量框架,通过使用`约定式`来进行api的快速生成,如果你想快速使用nodejs进行`RESTful API`开发,那么**qjs**是一个非常不错的选择

Downloads

191

Readme

什么是qjs?

qjs是一个基于fastify实现的轻量框架,通过使用约定式来进行api的快速生成,如果你想快速使用nodejs进行RESTful API开发,那么qjs是一个非常不错的选择

是否有集成案例?当然有,该框架我在内部项目已经使用已久,目前修复了一版并进行开源,以下是集成了qjs的相关项目

快速开始

npx create-qjs qjs-app && cd qjs-qpp
npm run start

项目结构

qjs-app/
│
├── db/                 # 数据库 (调用db接口才会创建)
│
├── functions/          # 云函数或其他功能模块(重点)
│
├── public/             # 对外公开目录
│
├── node_modules/       # 依赖包目录
│
├── package.json        # 项目配置文件
│
├── package-lock.json   # 依赖版本信息
└── README.md           # 项目说明文件        

如何使用?

通过上面的命令,你已经创建好了qjs项目,现在我们来一个个的分析:

  • package.json

    该目录里面的start命令是一个关键点,让我们看看里面启动命令:

    "scripts": {
      "start": "cross-env QJS_ROOTDIR=functions QJS_PORT=5173 QJS_PREFIX=/api QJS_STATIC=public run-qjs --init"
    }
    • QJS_PREFIX:路由前缀

      QJS_PREFIX=/api
          
      // route
      host:port/{QJS_PREFIX}/hello
    • QJS_PORT:qjs项目运行端口

    • QJS_STATIC:公开目录

    • QJS_ROOTDIR:云函数目录,你使用最频繁的地方,具体看functions

  • functions

    该目录为核心目录,如果你按照上面的命令进行创建并启动项目,那么qjs会自动创建functions目录,该目录为约定式api所在位置,其以文件名为api地址

    functions/
    │
    ├── hello._id.dash._name.mjs  # host:port/{QJS_PREFIX}/hello/{id}/dash/{name}
    │
    ├── hello.mjs                 # host:port/{QJS_PREFIX}/hello
    │
    ├── (DIR)                     # 以`()`包裹的为路由组,默认排除
    │   └── qjs.mjs               # host:port/{QJS_PREFIX}/qjs
    │
    └── DIR                       
        └── hello.mjs               # host:port/{QJS_PREFIX}/{DIR}/hello

函数相关

下面是默认函数示例:

// functions/qjs.mjs

// @see https://github.com/allmors/qjs/
// import qjs from 'fast-qjs/core';

export default async function (params, ctx) {
    // const User = await qjs.db.collection('user');
    // const user = await User.insertOne({ name: "Sam", email: '[email protected]' })

    // or 

    const User = await this.db.collection('user');
    const user = await User.insertOne({ name: "Sam", email: '[email protected]' })
    // ......

    return ctx.reply.send({
        message: 'Hello from qjs API',
        method: context.method,
        params: {
            ...user
        }
    });
}
  • params:

    • params.params host:port/${QJS_PREFIX}/qjs/:id/:name

    • params.query host:port/${QJS_PREFIX}/qjs?id=1321

    • params.body host:port/${QJS_PREFIX}/qjs==> POST/PUT Method

  • ctx

    • ctx.method

    • ctx.headers

    • ctx.reply

    • ...ctx

ctx完美继承了fastify,如果有需要,请查询fasify官方文档

示例中你可能看到了两段被注释的代码

// functions/qjs.mjs

// import qjs from 'fast-qjs/core';
// const User = await qjs.db.collection('user');
// const user = await User.insertOne({ name: "Sam", email: '[email protected]' })

// or 

// const User = await this.db.collection('user');
// const user = await User.insertOne({ name: "Sam", email: '[email protected]' })
// ......

为什么出现这两个,其实上面两段代码最终结果一样,因为qjs为了方便开发者提供了两套使用方案,你可以通过导入core包进行操作,或者直接使用this

qjs目前暴露了两个接口,一个是db另一个是files,它们见名知意,就是数据库的操作和文件操作

数据库相关

qjs使用bson进行数据存储,以下是qjs数据库提供的相关操作,请记住,fastify严格使用(async/await)

db.collection(collectionName)
db.listCollection()
await Collection.find(query, option)
await Collection.findOne(query)
await Collection.findById(_id)

await Collection.create(document)
await Collection.insertOne(document)
await Collection.insertMany(documents)

await Collection.deleteOne(query)
await Collection.deleteMany(query)
await Collection.findByIdAndDelete(_id)

await Collection.updateOne(query, payload, option)
await Collection.updateMany(query, payload)
await Collection.findByIdAndUpdate(_if, payload, option)

await Collection.export()

await Collection.count()
await Collection.drop()
await Collection.rename()

文件相关

目前qjs提供了文件相关的两个方法,分别是:

  • upload()

    /*
    * @fileObj File
    * @name string
    * @options Object
    * @options?.addOptions
    */
    async this.files.upload(fileObj:File, options = {})
  • delete()

    /*
    * @params {_id:string}
    */
    async this.files.delete(params = {})

JWT鉴权

qjs既然是轻量化的接口框架,当然也提供了JWT相关,目前qjs提供了以下与jwt相关的方法,qjs-jwt继承fast-jwt

  • sign()

    /*
    * @payload {name:"张三",...} as Object
    */
    async this.jwt.sign(payload:Object)
  • verify()

    /*
    * @token string
    */
    async this.jwt.verify(token:string)
  • Beare Token

    //继承在云函数的ctx中
    export default async function (params, ctx) {
           ctx.user
    }

完整示例

/**
 * @param {*} params
 * @ctx {request,reply,method,headers}
 * @see https://github.com/allmors/qjs
 */
export default async function (params, ctx) {
    /**
     * use db
     */
    const sql = await this.db.collection('_files')

    try {
        /**
         * if(ctx.method === 'PUT') {}
         * if(ctx.method === 'DELETE') {}
         * if(ctx.method === 'GET') {}
         */
        if (ctx.method === 'POST') {
            const { file } = params
            const res = await this.files.upload(file)
            return ctx.reply.send({
                message: 'Hello from test APIssfwe',
                method: ctx.method,
                params: {
                    ...res
                }
            });
        }

        // get files
        const file = await sql.findById(params.id);
        // const t = await qjs.files.delete({ _id: params.id });

        const token = await this.jwt.sign({ name: 'test' });

        // verify = user
        const verify = await this.jwt.verify(token);
        // const user = ctx.user

        return ctx.reply.send({
            message: 'Hello from test API',
            method: ctx.method,
            params: {
                token,
                verify,
                file
            }
        })
    } catch (error) {
        throw new Error(error)
    }
}

响应

{
    "message": "Hello from test API",
    "method": "GET",
    "params": {
        "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoidGVzdCIsImlhdCI6MTcyNzY1OTkyMn0.iC3m9WyOHdXVHbybiLveIxXaI7oX4Gu1dQWo7hotAT4",
        "verify": {
            "name": "test",
            "iat": 1727659922
        },
        "file": {
            "_id": "66f9fb5b00e6f64eb8b8fdb7",
            "url": "/uploads/05942efe-071e-42-1727658843191/deKGMl9.jpg",
            "name": "deKGMl9.jpg",
            "type": "image/jpeg",
            "size": 360969
        }
    }
}