Coder Social home page Coder Social logo

fastify-nuxt-api's Introduction

原作者地址: https://hire.jonasgalvez.com.br/2020/feb/22/the-ultimate-nuxt-api-setup/ 地址:https://www.homwang.com 欢迎大家性能测试 交流讨论——QQ 群号:604203227

#📦 思考 1、你是否也曾想过将 Nuxt 客户端和服务端切分开来? 2、你是否也曾想过基于自己服务器的部署 API? 3、你是否也曾想过在自己服务器上加点东西? 4、用 express、koa 搭建一个单独的服务是否过于复杂? 5、你真正想要的是什么?您永远不会知道什么是足够的,除非您知道什么是足够的。

#📦 模版 Demo 及 作者分享 github.com 地址(https://github.com/galvez/fastify-nuxt-api) 原文: https://hire.jonasgalvez.com.br/2020/feb/22/the-ultimate-nuxt-api-setup/ 经作者同意翻译中文分享,以及修改模版 Bug 以及添加项目构建、发布后的 github 地址:

#📦 项目结构

结构说明

Nuxt 插件: nuxt.js Nuxt 的渲染中间件IncommingMessageServerResponse  对象,它们可以通过req.raw和在 Fastify 中使用reply.res,所以我们有

const nuxt = new Nuxt({ dev: process.dev, ...nuxtConfig });
await nuxt.ready();

fastify.get("/*", (req, reply) => {
  nuxt.render(req.raw, reply.res);
});

在开发模式下设置构建过程:

if (process.dev) {
  process.buildNuxt = () => {
    return new Builder(nuxt).build().catch(buildError => {
      consola.fatal(buildError);
      process.exit(1);
    });
  };
}

不会立即构建 Nuxt,因为我们希望在加载程序插件有机会向包含所有 API 客户端方法的内部版本中添加自动生成的文件后再进行此操作。

万能的 API 加载器: loader.js 有一个包装fastify-esm-loader将被收集登记有关路由的数据,并使用这些数据来 CODEGEN 既为 SSR 和客户端消费者相关的 API 客户端的方法。

从收集所述数据开始: onRoute

const api = {};
const handlers = {};
fastify.addHook("onRoute", route => {
  const name = route.handler[methodPathSymbol];
  if (name) {
    const routeData = [route.method.toString(), route.url];
    setPath(api, name, routeData);
    setPath(handlers, name, route.handler);
  }
});
await FastifyESMLoader(fastify, options, done);
await fastify.ready();

有了apihandlers,我们可以使用中的功能gen.js自动构建以下客户端样板:

const clientMethods = generateClientAPIMethods(api);
const apiClientPath = resolve(__dirname, join("..", "client", "api.js"));
await writeFile(apiClientPath, clientMethods);

const serverMethods = generateServerAPIMethods(api);
const apiServerPath = resolve(__dirname, join("api.js"));
await writeFile(apiServerPath, serverMethods);

并在相同的代码块中完成构建: const getServerAPI = await import(apiServerPath).then(m => m.default) 生成代码并实时导入!下一部分将为 Fastify 路由处理程序提供类似于 axios的接口。设法得到它与可使用状态translateRequest,并在gen.js中提供translateRequestWithPayload。对于 SSR,我们可以直接在中使用该对象process.$api

process.$api = getServerAPI({
  handlers,
  translateRequest,
  translateRequestWithPayload
});

最后,触发 Nuxt 构建:

if (process.buildNuxt) {
  await process.buildNuxt();
}

translateRequest()方法: 它就像是 Fastify 路由处理程序的适配器,就像我们在模拟对它们的实时 HTTP 请求一样,但实际上不是。这是一个简化的代码段:

export function translateRequest(handler, params, url, options = {}) {
  return new Promise((resolve, reject) => {
    handler(
      {
        url,
        params,
        query: options.params,
        headers: options.headers
      },
      {
        send: data => {
          resolve({ data });
        }
      }
    );
  });
}

为什么要这样设置呢?因为是有好处的。我们不必在 SSR 期间对 API 调用发出实时 HTTP 请求!然后把所有这些东西交给 Nuxt。

在 Nuxt 中提供$api: 提供 API 和以往正常使用 API 一样,需要在插件中提供一个 api.js 然后将其注入到Nuxt当中,如果请求完全在服务器(SSR)上运行,将 process.$api直接分配给ctx.$api,这将直接运行 Fastify 路由处理提供的 API 方法。如果该应用程序已经在客户端上加载了,我们将使用getClientAPI自动生成的函数(在这里我将其导入为),并将其放置在中client/api.js

import getClientAPI from "../api";

export default (ctx, inject) => {
  if (process.server) {
    ctx.$api = process.$api;
  } else {
    ctx.$api = getClientAPI(ctx.$axios);
  }
  inject("api", ctx.$api);
};

server/routes/hello/msg.js

export default (req, reply) => {
  reply.send({ message: "Hello from API" });
};

然后在 Nuxt 页面中使用 asyncData:

<template>
  <main>
    <h1>{{ message }}</h1>
  </main>
</template>

<script>
export default {
  async asyncData ({ $api }) {
    const { data } = await $api.hello.msg()
    return data
  }
}
</script>

$api.hello.msg() 就不用再次写了,因为在启动项目的时候它会根据 server/routes 内容自动生成 api.js 文件,在client/api.js

依赖注入: 如果fastify-esm-loader检测到由导出的默认函数<service>/<handler>.js仅具有一个参数,它将使用它传递注入(从中的export routes/index.js),然后返回最终的处理函数。你就可以执行以下操作:

export default ({ injection }) => (req, reply) => {
  reply.send({ injection });
};

修改 bug 及项目构建流程

main.js 中 fastify-sensible 未被引用需要提前下载安装 fastify-sensible 模块 在package.json中配置:

{
"scripts": {
    "dev": "node index.js",//本地启动
    "build": "nuxt build client/",//添加打包
    "start": "NODE_ENV=production pm2 start index.js --name='HomWang'"//添加pm2进程守护
  },
}

结论

我同该作者一样认为 TypeScript 和 GraphQL 朝着极简主义的相反方向发展。 因为我们只想简单、方便、快捷的开发,不想将原来简单的东西复杂化。

API 自动化确实与 GraphQL 有关,尽管看上去像 Fastify 和 Nuxt API 样板一样复杂,但其所有代码的总和仍然远远低于任何基于 GraphQL 的解决方案的总和,并且 SSR 中没有 HTTP 请求发生。

就速度而言,通过 Fastify 的服务、Nuxt 的性能与从其内置的基于连接的服务器服务 Nuxt 的性能大致相同,避免对 SSR API 调用的 HTTP 请求可以真正改善高 SSR 负载

最重要的是,与 Fastify 的大量堆栈相比,能够使用 Fastify 的插件组织代码似乎使设置更加容易,serverMiddleware更易于维护。

fastify-nuxt-api's People

Contributors

516310460 avatar

Stargazers

 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.