【问题标题】:How do you implement a Sveltekit Post endpoint which makes an async DB request?您如何实现发出异步数据库请求的 Sveltekit Post 端点?
【发布时间】:2021-12-17 10:21:18
【问题描述】:

因此,当我访问 SvelteKit 发布端点时,如果我提交了一些值并且它们没有通过验证检查,它就可以正常工作。它返回正确的状态和正文。但是,当它进行数据库插入时,端点返回 404 错误,但它将用户插入数据库正常。我认为这是因为 DB 调用是异步的,并且 SvelteKit 没有等待结果返回,但不确定如何更改我的代码,所以它等待并发送正确的 json 响应。

感谢您的帮助!

import type { EndpointOutput } from '@sveltejs/kit';
import bcrypt from 'bcrypt';
import { randomUUID } from 'crypto';
import db from '$lib/config/db.js';
import { roles } from '$lib/config/roles.js';
import validation from '$lib/_helpers/validation';

export async function post({
    body
}: {
    body: { firstName: string; lastName: string; emailAddress: string; password: string };
}): Promise<EndpointOutput> {
    //lets trim any whitespace on the fields
    console.log(body);
    const firstName = body?.firstName.trim();
    const lastName = body?.lastName.trim();
    const email = body?.emailAddress.trim();
    const password = body?.password.trim();
    const userRole = roles.web + roles.anonymous;
    const bcryptPassword = await bcrypt.hash(password, 10);
    const emailToken = randomUUID();
    // double check the validation on the fields in case user submits directly to this endpoint.
    if (validation.validateEmail(email) == false) {
        //console.log(email);
        return {
            status: 422,
            body: {
                message: 'Please enter a valid email address.'
            }
        };
    }
    if (validation.validatePassword(password) == false) {
        return {
            status: 422,
            body: {
                message: 'Password must be at least 6 characters.'
            }
        };
    }
    if (validation.validateNotEmpty(firstName) == false) {
        return {
            status: 422,
            body: {
                message: 'First Name is required.'
            }
        };
    }
    if (validation.validateDisplayName(lastName) == false) {
        return {
            status: 422,
            body: {
                message: 'Last Name is required.'
            }
        };
    }

//insert user
    await db.query(
        'INSERT INTO users (first_name, last_name, email, user_password, user_role, email_verification_token) VALUES ($1, $2, $3, $4, $5, $6)',
        [firstName, lastName, email, bcryptPassword, userRole, emailToken],
        (error, results) => {
            // console.log(error, results);
            if (error) {
                return {
                    status: 417,
                    body: {
                        message: error.toString()
                    }
                };
            }
            //console.log(results);
            return {
                status: 201,
                body: {
                    message: 'User created successfully'
                }
            };
        }
    );
}

更新修复

我最终使用 pg-promise 包而不是 pg 包来连接我的数据库。

以下是更新后的代码,以防有人遇到类似问题。

import type { EndpointOutput } from '@sveltejs/kit';
import bcrypt from 'bcrypt';
import { randomUUID } from 'crypto';
import { roles } from '$lib/config/roles.js';
import validation from '$lib/_helpers/validation';
import { db } from '$lib/config/db.js';

export async function post({
    body
}: {
    body: { firstName: string; lastName: string; emailAddress: string; password: string };
}): Promise<EndpointOutput> {
    //lets trim any whitespace on the fields
    console.log(body);
    const firstName = body?.firstName.trim();
    const lastName = body?.lastName.trim();
    const email = body?.emailAddress.trim();
    const password = body?.password.trim();
    const userRole = roles.web + roles.anonymous;
    const bcryptPassword = await bcrypt.hash(password, 10);
    const emailToken = randomUUID();
    // double check the validation on the fields in case user submits directly to this endpoint.
    if (validation.validateEmail(email) == false) {
        //console.log(email);
        return {
            status: 422,
            body: {
                message: 'Please enter a valid email address.'
            }
        };
    }
    if (validation.validatePassword(password) == false) {
        return {
            status: 422,
            body: {
                message: 'Password must be at least 6 characters.'
            }
        };
    }
    if (validation.validateNotEmpty(firstName) == false) {
        return {
            status: 422,
            body: {
                message: 'First Name is required.'
            }
        };
    }
    if (validation.validateDisplayName(lastName) == false) {
        return {
            status: 422,
            body: {
                message: 'Last Name is required.'
            }
        };
    }

    //check if user already exists.
    const userAlreadyExists = await db.oneOrNone('SELECT email from users WHERE email=$1 LIMIT 1', [
        email
    ]);
    console.log(' result: ' + userAlreadyExists);
    if (userAlreadyExists) {
        return {
            status: 409,
            body: {
                message: 'User with that email already exists'
            }
        };
    }

    try {
        // insert New user into DB
        await db.none(
            'INSERT INTO users (first_name, last_name, email, user_password, user_role, email_verification_token) VALUES ($1, $2, $3, $4, $5, $6)',
            [firstName, lastName, email, bcryptPassword, userRole, emailToken]
        );

        return {
            status: 201,
            body: {
                message: 'User created successfully'
            }
        };
    } catch (error) {
        return {
            status: 417,
            body: {
                message: error.toString()
            }
        };
    }
}

【问题讨论】:

    标签: typescript postgresql sveltekit


    【解决方案1】:

    您的问题是您使用的数据库是通过回调系统function query(queryString, callback) 实现的,而您的await 并没有等待,实际上回调中的return 也没有从您的端点返回。

    最好的办法是检查您的数据库库是否有异步方法,您可以在其中执行类似或类似的操作:

    const { errror, result } = await db.query(....)
    

    这样应用程序实际上会等待查询完成。

    【讨论】:

    • 非常感谢!我最终将我的数据库库从 pg 切换到 pg-promise。这解决了我的麻烦。我会发布我更新的代码,以防其他人遇到这个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-10
    • 2016-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-17
    • 1970-01-01
    相关资源
    最近更新 更多