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

http-yyds

v0.6.5

Published

一个注解风格的 TypeScript HTTP Server。适用于封装 API 或个人小项目。目前还未到 1.0.0 版本,切勿用在生产环境。

Downloads

41

Readme

http-yyds

一个注解风格的 TypeScript HTTP Server。适用于封装 API 或个人小项目。目前还未到 1.0.0 版本,切勿用在生产环境。

安装

npm install http-yyds

项目配置

因为使用了装饰器和元数据反射,需要在 tsconfig.json 中加入以下开启以下配置项:

{
    "compilerOptions": {
        "target": "es2021",
        "module": "esnext",
        "experimentalDecorators": true,
        "emitDecoratorMetadata": true,
        "moduleResolution": "node"
    }
}

示例

import { App } from "http-yyds";

let app = new App("127.0.0.1", 8080);

class Test {
    @app.get("/hello")
    hello(name: string) {
        return `Hello ${name}!`;
    }

    @app.get("/person/{name}/sex")
    getCurTime(name: string) {
        if (name == "xiaoming") {
            return `man`;
        } else if (name == "xiaohong") {
            return "woman";
        } else {
            return "unknown";
        }
    }

    @app.post("/cal/sum")
    sum(a: number, b: number) {
        return `${a}+${b}=${a + b}`;
    }
    
    @app.get("/api/person/{name}/info")
    getPersion(name: string) {
        if (name == "xiaoming") {
            return { sex: "man", name: "xiaoming", age: 18 };
        } else if (name == "xiaohong") {
            return { sex: "woman", name: "xiaohong", age: 19 };
        } else {
            throw new Error(`${name} 的信息不存在`);
        }
    }
}

app.listen();

功能

用注解映射请求路径和响应方法

http-yyds 提供的注解 API 可以根据请求路径和请求方法将请求映射到响应方法,方法可以是同步方法,也可以是异步方法。

例如,下面将路径 "/hello" 的 GET 请求映射到方法 hello(name:string)

@app.get("/hello")
hello(name: string) {
    return `Hello ${name}!`;
}

还可以将多个请求路径映射到同一个响应方法,只要叠加注解就行:

@app.get("/")
@app.get("/index")
getIndex() {
    // 省略。。。
}

支持 HTTP GET、POST、PUT、DELETE

App 类内置了以下方法注解,用于支持常用的 HTTP 请求方法。

interface App {
    get(path: string);
    post(path: string);
    put(path: string);
    delete(path: string);
}

参数 path 表示请求的路径。

对于没有内置支持的 HTTP 请求方法,未来会提供一个扩展方法 mapping(path: string, method: string) 让用户自定定义方法注解。

自动提取和填充参数

http-yyds 会自动从请求中提取参数,并将参数填充为响应方法中的同名实参。

URL 中的查询参数

例如前面的示例中的代码片段:

@app.get("/hello")
hello(name: string) {
    return `Hello ${name}!`;
}

收到请求时会自动提取请求 URL 中的查询参数:

$ curl http://127.0.0.1:8080/hello?name=xiaoming
hello xiaoming!

路径参数

例如前面的示例中的代码片段:

@app.get("/person/{name}/sex")
getCurTime(name: string) {
    if (name == "xiaoming") {
        return `man`;
    } else if (name == "xiaohong") {
        return "woman";
    } else {
        return "unknown";
    }
}

收到请求后会自动将路径中的 name 参数:

$ curl http://127.0.0.1:8080/person/xiaoming/sex
man
$ curl http://127.0.0.1:8080/person/xiaohong/sex
woman
$ curl http://127.0.0.1:8080/person/xiaohong/sex
woman
$ curl http://127.0.0.1:8080/person/unknown/sex
unknown

POST 请求体中的参数

例如前面的示例中的代码片段:

 @app.post("/cal/sum")
sum(a: number, b: number) {
    return `${a}+${b}=${a + b}`;
}
application/x-www-form-urlencoded 格式的参数
$ curl -d 'a=1&b=2' http://127.0.0.1:8080/cal/sum
1+2=3
application/json 格式的参数
$ curl -H 'Content-Type: application/json'  -d '{"a":1,"b":2}' http://127.0.0.1:8080/cal/sum
1+2=3

自动处理响应函数的返回

http-yyds 会自动将响应方法的返回封装成 HTTP 响应。

将字符串类型的返回转成 text/plain 类型的 HTTP 响应:

@app.get("/person/{name}/sex")
getCurTime(name: string) {
    if (name == "xiaoming") {
        return `man`;
    } else if (name == "xiaohong") {
        return "woman";
    } else {
        return "unknown";
    }
}
$ curl -i http://127.0.0.1:8080/person/xiaohong/sex                             HTTP/1.1 200 OK
Content-Type: text/plain;charset=UTF-8
Date: Fri, 07 Jan 2022 12:22:44 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Transfer-Encoding: chunked

woman

将对象类型的响应转成 application/json 类型的 HTTP 响应:

 @app.get("/api/person/{name}/info")
getPersion(name: string) {
    if (name == "xiaoming") {
        return { sex: "man", name: "xiaoming", age: 18 };
    } else if (name == "xiaohong") {
        return { sex: "woman", name: "xiaohong", age: 19 };
    } else {
        throw new Error(`${name} 的信息不存在`);
    }
}
$ curl -i http://127.0.0.1:8080/api/person/xiaoming/info
HTTP/1.1 200 OK
Content-Type: application/json
Date: Fri, 07 Jan 2022 12:40:15 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Transfer-Encoding: chunked

{"sex":"man","name":"xiaoming","age":18}

如果响应函数抛出异常,也能将其转成 500 响应返回:

$ curl -i http://127.0.0.1:8080/api/person/xxx/info
HTTP/1.1 500 Internal Server Error
Content-Type: application/json
Date: Fri, 07 Jan 2022 12:40:51 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Transfer-Encoding: chunked

{"message":"服务内部出错:Error: xxx 的信息不存在"}

如果自动返回不满足需求,http-yyds 还提供了一个 Response 类用于自定义返回:

例如,下面返回一个 html 文件:

import { App, Response } from "http-yyds";

@app.get("/")
@app.get("/index")
getIndex() {
    return new Response(
        200,
        "OK",
        { "Content-Type": contentType },
        "<h1>Hello World!</h1>"
    );
}

自动处理错误请求

如果请求路径不存在对应的响应方法,则自动返回 404:

$ curl -i http://127.0.0.1:8080/api/xx
HTTP/1.1 404 Not Found
Content-Type: application/json
Date: Fri, 07 Jan 2022 12:45:15 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Transfer-Encoding: chunked

{"message":"未找到/api/xx对应的资源"}

如果请求对应的路径存在响应方法,但是不特定 HTTP 请求方法,则自动返回 405 响应:

$ curl -i http://127.0.0.1:8080/cal/sum
HTTP/1.1 405 Method Not Allowed
Allow: POST
Content-Type: application/json
Date: Fri, 07 Jan 2022 12:47:23 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Transfer-Encoding: chunked

{"message":"/cal/sum对应的资源不支持GET"}

未来会支持更多类型的自动响应。

todo

  • [ ] 完成面向切面的拦截器
  • [ ] 提供映射基础路径和处理器类的注解
  • [ ] 支持用户自己实例化处理器类

注意

  • 在未发布 1.0.0 版本前,http-yyds 的接口会随着作者的经验和品味变化。
  • http-yyds 基于的装饰器和元数据反射都处于”建议征集的第二阶段“,不知道什么时候出现在正式标准中。
  • 毕竟是个人作品,在发布 1.0.0 之前不要用于生产环境。