You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js GraphQL对接Azure SQL返回空字段问题求助

问题:GraphQL API从Azure SQL获取数据后返回字段为空

我正在开发一个GraphQL API,从Azure SQL读取数据并仅返回请求的属性。目前已确认SQL能成功读取到正确记录,但响应中的所有字段均为空,怀疑问题出在SQL返回的Promise处理环节,求修复帮助。


相关代码

var express = require('express');
var app = express();
var fs = require("fs");
const expressGraphQL = require('express-graphql').graphqlHTTP
//app.use(express.json());

var TYPES = require('tedious').TYPES;
const sql = require('mssql');

const dotenv = require("dotenv")
dotenv.config()

var { buildSchema } = require('graphql');

var schema = buildSchema(`
    type Query {
        course(id: Int!): Course
        courses(topic: String): [Course]
    },
    type Course {
        id: Int
        title: String
        author: String
        description: String
        topic: String
        url: String
    }
`);

var config = {
    server: "xxxxxxxx.database.windows.net",
    user: process.env.SQLUSERNAME,
    password: process.env.SQLPSWRD,
    database: "xxxxxx",
    options: {
        trustedconnection: true,
        enableArithAbort : true
    }
};

async function readsql(id) {
    console.log('Reading SQL with id :' + id);
    try {
        let pool = await sql.connect(config);
        let products = await pool.request().query("select * FROM [TestSchema].[Courses] WHERE [id] =" + id);
        //console.log(products.recordsets);
        return products.recordsets;
    }
    catch (error) {
        console.log(error);
    }
}

var getCourse = function(args) { 
    var id = args.id;
    console.log("Getting a course "  + args);
    return new Promise(function(resolve, reject){
        readsql(id).then(result => {
            console.log("Inside : ");
            console.log(result[0]);
            return resolve(result[0].filter(course => {
            //return promiseData(result[0]).filter(course => {
                console.log(course.id);
                console.log(id);
                return course.id == id;            
            }));
        })
    })
}

let promiseData = () => {
    return new Promise((resolve, reject) => {
        getCourse((course) => {
            resolve(course);
        });
    });
};

// The root provides a resolver function for each API endpoint
var root = {
    course: getCourse,
};

app.use('/graphql', expressGraphQL({
    schema: schema,
    rootValue: root,
    graphiql: true
}));

var server = app.listen(8081, function () {
   var host = server.address().address
   var port = server.address().port
   console.log("Example app listening at http://%s:%s", host, port)
})

GraphQL查询语句

query getSingleCourse($courseID: Int!) {
    course(id: $courseID) {
        title
        author
        description
        topic
        url
    }
}

查询变量

{ 
    "courseID":1
}

响应结果

{
    "data": {
        "course": {
            "title": null,
            "author": null,
            "description": null,
            "topic": null,
            "url": null
        }
    }
}

修复方案

问题集中在Promise处理逻辑、数据格式匹配和SQL安全性三个方面,修复如下:

1. 修正readsql函数(解决数据格式+SQL注入问题)

SQL查询已通过WHERE id=xxx过滤出单条记录,无需后续再做filter;同时改用参数化查询避免注入风险,直接返回单条记录对象:

async function readsql(id) {
    console.log('Reading SQL with id :' + id);
    try {
        let pool = await sql.connect(config);
        // 参数化查询,避免SQL注入
        let products = await pool.request()
            .input('id', TYPES.Int, id)
            .query("select * FROM [TestSchema].[Courses] WHERE [id] = @id");
        // 返回第一条匹配的记录(ID唯一)
        return products.recordsets[0][0];
    }
    catch (error) {
        console.log(error);
        throw error; // 抛出错误让GraphQL统一处理
    }
}

2. 简化getCourse函数(消除冗余Promise嵌套)

利用readsql本身的async特性,直接返回Promise结果,避免手动包装Promise:

var getCourse = async function(args) { 
    var id = args.id;
    console.log("Getting a course with id: " + id);
    return await readsql(id);
}

3. 移除无用代码

删除未被使用的promiseData函数,精简代码结构。

修改后,GraphQL会收到与Course类型完全匹配的对象,即可正确返回对应字段值。


内容的提问来源于stack exchange,提问作者Anupam Chand

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 14:43:18