Path parameters placed into query
chasent opened this issue · comments
I have noticed that when using path and query parameters together, the formatter toString()
function returns a URI with the path parameters.
For example:
const t = require('io-ts')
const fpr = require('fp-ts-routing')
const result = fpr.lit('accounts')
.then(fpr.str('accountId'))
.then(fpr.lit('files'))
.then(fpr.query(t.interface({ pathparam: t.string })))
.formatter
.run(fpr.Route.empty, { accountId: 'testId', pathparam: '123' })
.toString()
// result -> /accounts/testId/files?accountId=testId&pathparam=123
Is this behavior intended?
Looking at the implementation of the query function, it could possibly be modified so that only properties in the io-ts type are added tothe query.
Thanks,
Marc.
It would seem that the type.encode
function from io-ts does not remove excess proeprties. As a workaround, I created a query function that uses only the types of the query.
export function query<A extends object, T>(type: t.InterfaceType<A, Record<keyof T, fpr.QueryValues>>): fpr.Match<A> {
return new fpr.Match(
new fpr.Parser((r: any) => { throw new Error() }),
new fpr.Formatter((r, query: any) => {
const p = r.parts
const q = type.encode(Object.keys(type.props).reduce<any>((p, key) => ({ ...p, [key]: query[key] }), {} as any))
return new fpr.Route(p, q)
})
)
}
It would seem that the type.encode function from io-ts does not remove excess proeprties
@chasent that's right, io-ts
's interface
doesn't cut excess properties. In order to do that you can use strict
instead
assert.strictEqual(
fpr
.lit('accounts')
.then(fpr.str('accountId'))
.then(fpr.lit('files'))
.then(fpr.query(t.strict({ pathparam: t.string })))
.formatter.run(fpr.Route.empty, { accountId: 'testId', pathparam: '123' })
.toString(),
'/accounts/testId/files?pathparam=123'
)
@chasent I've added some documentation, thanks for pointing out.