Add ability to call idempotent methods via GET request
This commit is contained in:
parent
c273c1b914
commit
e6a98bb450
@ -1,13 +1,14 @@
|
|||||||
import {FunctionPropertyNames} from './types'
|
import {FunctionPropertyNames} from './types'
|
||||||
import {NextFunction, Request, Response, Router} from 'express'
|
import {NextFunction, Request, Response, Router} from 'express'
|
||||||
import {createRpcService, ERROR_SERVER} from './jsonrpc'
|
import {createRpcService, ERROR_SERVER, ERROR_INVALID_PARAMS} from './jsonrpc'
|
||||||
import {createError, isJSONRPCError, IJSONRPCError} from './error'
|
import {createError, isJSONRPCError, IJSONRPCError} from './error'
|
||||||
|
import {IDEMPOTENT_METHOD_REGEX} from './idempotent'
|
||||||
|
|
||||||
export type TGetContext<Context> = (req: Request) => Context
|
export type TGetContext<Context> = (req: Request) => Context
|
||||||
|
|
||||||
export function jsonrpc<Context>(
|
export function jsonrpc<Context>(
|
||||||
getContext: TGetContext<Context>,
|
getContext: TGetContext<Context>,
|
||||||
idempotentMethodRegex = /^(find|fetch|get)/,
|
idempotentMethodRegex = IDEMPOTENT_METHOD_REGEX,
|
||||||
) {
|
) {
|
||||||
return {
|
return {
|
||||||
/**
|
/**
|
||||||
@ -22,31 +23,50 @@ export function jsonrpc<Context>(
|
|||||||
|
|
||||||
const router = Router()
|
const router = Router()
|
||||||
|
|
||||||
|
function handleResponse(response: any, res: Response) {
|
||||||
|
if (response === null) {
|
||||||
|
// notification
|
||||||
|
res.status(204).send()
|
||||||
|
} else {
|
||||||
|
res.json(response)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
router.get('/', (req, res, next) => {
|
||||||
|
if (!idempotentMethodRegex.test(req.query.method)) {
|
||||||
|
// TODO fix status code and error type
|
||||||
|
const err = createError(ERROR_SERVER, {
|
||||||
|
id: req.query.id,
|
||||||
|
data: null,
|
||||||
|
statusCode: 400,
|
||||||
|
})
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
callRpcService(req.query, getContext(req))
|
||||||
|
.then(response => handleResponse(response, res))
|
||||||
|
.catch(next)
|
||||||
|
})
|
||||||
|
|
||||||
router.post('/', (req, res, next) => {
|
router.post('/', (req, res, next) => {
|
||||||
callRpcService(req.body, getContext(req))
|
callRpcService(req.body, getContext(req))
|
||||||
.then(response => {
|
.then(response => handleResponse(response, res))
|
||||||
if (response === null) {
|
.catch(next)
|
||||||
// notification
|
|
||||||
res.status(204).send()
|
|
||||||
} else {
|
|
||||||
res.json(response)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(err => handleError(req.body.id, err, req, res, next))
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
router.use('/', handleError)
|
||||||
|
|
||||||
return router
|
return router
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleError(
|
function handleError(
|
||||||
id: number | string | null,
|
|
||||||
err: any,
|
err: any,
|
||||||
req: Request,
|
req: Request,
|
||||||
res: Response,
|
res: Response,
|
||||||
next: NextFunction,
|
next: NextFunction,
|
||||||
) {
|
) {
|
||||||
|
const id = req.method === 'POST' ? req.body.id : req.query.id
|
||||||
// TODO log error
|
// TODO log error
|
||||||
// TODO make this nicer
|
// TODO make this nicer
|
||||||
|
|
||||||
|
|||||||
1
packages/jsonrpc/src/idempotent.ts
Normal file
1
packages/jsonrpc/src/idempotent.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export const IDEMPOTENT_METHOD_REGEX = /^(find|fetch|get)/
|
||||||
Loading…
x
Reference in New Issue
Block a user