如何通过 REST API 在 Express Gateway 中使用多个路径和端点?

Posted

技术标签:

【中文标题】如何通过 REST API 在 Express Gateway 中使用多个路径和端点?【英文标题】:How do i use multiple paths and endpoints in Express Gateway with my RESTAPI? 【发布时间】:2021-06-19 03:39:00 【问题描述】:

目前正在开发处理对 RESTAPI 和 GraphQL 微服务的调用的 Express Gateway。 GraphQL 管道运行良好,但 RESTAPI 的管道是我正在努力解决的问题。

我制作了一个简单的 CRUD 功能 RESTAPI,可以创建、阅读、更新和删除书籍和作者。他们有多种途径可以做到这一点,例如:http://localhost:4001/books/add。

问题是我真的不明白如何在快速网关中转换这些路由或路径,以便我可以通过网关到达它们。

这是我当前的代码,config.yml:

http:
  port: 8080
admin:
  port: 9876
  host: localhost
apiEndpoints:
  restapi:
    host: localhost
    paths: '/rp'
  graphql:
    host: localhost
    paths: '/gql'
serviceEndpoints:
  restapi:
    url: 'http://localhost:4001/'    
  graphql:  
    url: 'http://localhost:4000'
policies:
  - proxy
pipelines:
  restapi:
    apiEndpoints:
      - restapi
    policies:
      - proxy:
          - action: 
              serviceEndpoint: restapi
              changeOrigin: true
              ignorePath: false
              prependPath: true
              stripPath: true
              
  graphql:
    apiEndpoints:
      - graphql
    policies:
      - proxy:
          - action:
              serviceEndpoint: graphql
              changeOrigin: true

这是restapi书的代码:

const express = require('express');
const mongoose = require('mongoose');
const book = require('../models/book');
const  findById  = require('../models/book');
const router = express.Router();
const Book = require('../models/book');

//read all books
router.get('/', async (req, res) =>
    try
        const AllBooks = await Book.find();
        res.json(AllBooks);
    catch(err)
        res.json(message:err);
    
    
)

//create book
router.post('/add', async (req, res) => 
    var NewBook = new Book(
        title: req.body.title,
        pages: req.body.pages
    )
    try
        const SavedBook = await NewBook.save();
        res.json(SavedBook);
    catch(err)
        res.json(message: err)
    
)

//read book
router.get('/:BookId', async (req, res) => 
    try
        const ReadBook = await Book.findById(req.params.BookId);
        res.json(ReadBook);
    catch(err)
        res.json(message: err);
        
)

//update book
router.patch('/update/:BookId', async (req, res) => 
    try
        const updatedBook = await Book.updateOne(_id: req.params.BookId,
            $set: title: req.body.title, pages: req.body.pages);
        res.json(updatedBook);
    catch(err)
        res.json(message: err);
        
)

//delete book
router.delete('/delete/:BookId', async (req, res) => 
    try
         const DelBook = await Book.findById(req.params.BookId);
         DelBook.delete();
         res.send(DelBook + " Deleted");
    catch(err)
        res.json(message: err);
    
)



module.exports = router;

现在当我调用:http://localhost:4001/rp 时,它会返回“restapi”,就像我告诉的那样。 但是当我调用:http://localhost:4001/rp/books 时,它返回一个“CANNOT GET”,这是合乎逻辑的,因为我没有定义这个路径。一开始我以为快递网关会自动理解这一点。

我必须对所有路径进行硬编码吗?

我希望有人能给我解释一下,因为快递网关没有像我这样的例子。 :)

【问题讨论】:

【参考方案1】:

我找到了解决办法。

我对 apiEndpoint 和 serviceEndpoint 之间的定义感到困惑。

答案是:是的,您必须硬编码其中的所有路径,但这只会在“apiEndpoints”下。

看起来像这样:

apiEndpoints:
  restapi:
    host: localhost
    paths: 
       - '/books'
       - '/books/add'
       - '/authors'
       - '/authors/...'
serviceEndpoints:
  restapi:
    url: 'http://localhost:4001'

所以总而言之,只有一个服务具有多个 api 端点,这听起来很合逻辑。

我认为一个缺点是当有很多服务时,这个配置文件会变成一大堆端点。

【讨论】:

以上是关于如何通过 REST API 在 Express Gateway 中使用多个路径和端点?的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 REST API 微服务(使用 Express 构建)将 MongoDB 更改流与节点 js 一起使用

通过 Paypal Express Checkout REST API 定期付款

使用 PayPal REST API 通过 Express Checkout 测试拒绝付款

如何使用 Advanced REST Client 或 Postman 测试 Express/node REST API 后端?

如何对使用 Express + Mongoose 构建的 NodeJs REST API 服务器进行单元测试?

通过 Braintree SDK 的 Paypal Express Checkout 突然失败(缺少服务商 REST API 应用程序?)