Add ability to call idempotent methods via GET request

This commit is contained in:
Jerko Steiner 2019-08-04 10:19:42 +07:00
parent c273c1b914
commit e6a98bb450
2 changed files with 33 additions and 12 deletions

View File

@ -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

View File

@ -0,0 +1 @@
export const IDEMPOTENT_METHOD_REGEX = /^(find|fetch|get)/