Skip to content

Commit

Permalink
feat: filter GET handler using search params
Browse files Browse the repository at this point in the history
close #69
  • Loading branch information
marcosvega91 committed Apr 15, 2021
1 parent 6a2c049 commit 035ab01
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ function createModelApi<
return generateGraphQLHandlers(modelName, declaration, api, baseUrl)
}

return generateRestHandlers(modelName, primaryKey, api, baseUrl)
return generateRestHandlers(modelName, declaration, api, baseUrl)
},
}

Expand Down
30 changes: 26 additions & 4 deletions src/model/generateRestHandlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ import {
ModelDictionary,
ModelAPI,
PrimaryKeyType,
ModelDeclaration,
Value,
} from '../glossary'
import { GetQueryFor } from '../query/queryTypes'
import { GetQueryFor, QuerySelectorWhere } from '../query/queryTypes'
import { OperationErrorType, OperationError } from '../errors/OperationError'
import { removeInternalProperties } from '../utils/removeInternalProperties'
import { findPrimaryKey } from '../utils/findPrimaryKey'

interface WeakQuerySelectorWhere<KeyType extends PrimaryKeyType> {
[key: string]: Partial<GetQueryFor<KeyType>>
Expand Down Expand Up @@ -59,15 +62,34 @@ export function withErrors<RequestBodyType = any, RequestParamsType = any>(
}
}

function getFilters<
Dictionary extends ModelDictionary,
ModelName extends string
>(
searchParams: URLSearchParams,
declaration: ModelDeclaration,
): QuerySelectorWhere<any> {
const filters: QuerySelectorWhere<any> = {}
searchParams.forEach((value, key) => {
if (declaration[key]) {
filters[key] = {
equals: value,
}
}
})
return filters
}

export function generateRestHandlers<
Dictionary extends ModelDictionary,
ModelName extends string
>(
modelName: ModelName,
primaryKey: PrimaryKeyType,
modelDeclaration: ModelDeclaration,
model: ModelAPI<Dictionary, ModelName>,
baseUrl: string = '',
) {
const primaryKey = findPrimaryKey(modelDeclaration)!
const modelPath = pluralize(modelName)
const buildUrl = createUrlBuilder(baseUrl)

Expand All @@ -78,12 +100,12 @@ export function generateRestHandlers<
const cursor = req.url.searchParams.get('cursor')
const rawSkip = req.url.searchParams.get('skip')
const rawTake = req.url.searchParams.get('take')
const filters = getFilters(req.url.searchParams, modelDeclaration)

const skip = parseInt(rawSkip ?? '0', 10)
const take = rawTake == null ? rawTake : parseInt(rawTake, 10)

let options = { where: {} }

let options = { where: filters }
if (take && !isNaN(take) && !isNaN(skip)) {
options = Object.assign(options, { take, skip })
}
Expand Down
92 changes: 92 additions & 0 deletions test/model/toRestHandlers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const db = factory({
user: {
id: primaryKey(random.uuid),
firstName: name.firstName,
lastName: name.lastName,
},
})

Expand Down Expand Up @@ -44,10 +45,12 @@ describe('GET /users', () => {
db.user.create({
id: 'abc-123',
firstName: 'John',
lastName: 'White',
})
db.user.create({
id: 'def-456',
firstName: 'Kate',
lastName: 'Moen',
})

const res = await fetch('http://localhost/users')
Expand All @@ -58,10 +61,12 @@ describe('GET /users', () => {
{
id: 'abc-123',
firstName: 'John',
lastName: 'White',
},
{
id: 'def-456',
firstName: 'Kate',
lastName: 'Moen',
},
])
})
Expand All @@ -71,18 +76,22 @@ describe('GET /users', () => {
db.user.create({
id: 'abc-123',
firstName: 'John',
lastName: 'White',
})
db.user.create({
id: 'def-456',
firstName: 'Kate',
lastName: 'Moen',
})
db.user.create({
id: 'ghi-789',
firstName: 'Joseph',
lastName: 'Sipes',
})
db.user.create({
id: 'xyz-321',
firstName: 'Eva',
lastName: 'Grant',
})

const res = await fetch('http://localhost/users?skip=1&take=2')
Expand All @@ -92,10 +101,12 @@ describe('GET /users', () => {
{
id: 'def-456',
firstName: 'Kate',
lastName: 'Moen',
},
{
id: 'ghi-789',
firstName: 'Joseph',
lastName: 'Sipes',
},
])
})
Expand All @@ -105,18 +116,22 @@ describe('GET /users', () => {
db.user.create({
id: 'abc-123',
firstName: 'John',
lastName: 'White',
})
db.user.create({
id: 'def-456',
firstName: 'Kate',
lastName: 'Moen',
})
db.user.create({
id: 'ghi-789',
firstName: 'Joseph',
lastName: 'Sipes',
})
db.user.create({
id: 'xyz-321',
firstName: 'Eva',
lastName: 'Grant',
})

const res = await fetch('http://localhost/users?cursor=def-456&take=2')
Expand All @@ -126,10 +141,72 @@ describe('GET /users', () => {
{
id: 'ghi-789',
firstName: 'Joseph',
lastName: 'Sipes',
},
{
id: 'xyz-321',
firstName: 'Eva',
lastName: 'Grant',
},
])
})

it('return filtered entities', async () => {
server.use(...db.user.toHandlers('rest', 'http://localhost'))
db.user.create({
id: 'abc-123',
firstName: 'John',
lastName: 'White',
})
db.user.create({
id: 'def-456',
firstName: 'Kate',
lastName: 'Moen',
})
db.user.create({
id: 'def-789',
firstName: 'Kate',
lastName: 'Hilll',
})
const res = await fetch(
'http://localhost/users?firstName=Kate&lastName=Moen',
)
const users = await res.json()

expect(users).toEqual([
{
id: 'def-456',
firstName: 'Kate',
lastName: 'Moen',
},
])
})

it('return all entities when wrong filter param is provided', async () => {
server.use(...db.user.toHandlers('rest', 'http://localhost'))
db.user.create({
id: 'abc-123',
firstName: 'John',
lastName: 'White',
})
db.user.create({
id: 'def-456',
firstName: 'Kate',
lastName: 'Moen',
})
const res = await fetch('http://localhost/users?surname=Kate')
const users = await res.json()

expect(users).toEqual([
{
id: 'abc-123',
firstName: 'John',
lastName: 'White',
},
{
id: 'def-456',
firstName: 'Kate',
lastName: 'Moen',
},
])
})
Expand All @@ -141,10 +218,12 @@ describe('GET /users/:id', () => {
db.user.create({
id: 'abc-123',
firstName: 'John',
lastName: 'White',
})
db.user.create({
id: 'def-456',
firstName: 'Kate',
lastName: 'Moen',
})

const res = await fetch('http://localhost/users/def-456')
Expand All @@ -154,6 +233,7 @@ describe('GET /users/:id', () => {
expect(user).toEqual({
id: 'def-456',
firstName: 'Kate',
lastName: 'Moen',
})
})

Expand All @@ -162,6 +242,7 @@ describe('GET /users/:id', () => {
db.user.create({
id: 'abc-123',
firstName: 'John',
lastName: 'White',
})

const res = await fetch('http://localhost/users/xyz-321')
Expand All @@ -187,6 +268,7 @@ describe('POST /users', () => {
body: JSON.stringify({
id: 'abc-123',
firstName: 'Joseph',
lastName: 'Sipes',
}),
})
const user = await res.json()
Expand All @@ -195,6 +277,7 @@ describe('POST /users', () => {
expect(user).toEqual({
id: 'abc-123',
firstName: 'Joseph',
lastName: 'Sipes',
})
})

Expand Down Expand Up @@ -230,6 +313,7 @@ describe('PUT /users/:id', () => {
db.user.create({
id: 'abc-123',
firstName: 'John',
lastName: 'White',
})

const res = await fetch('http://localhost/users/abc-123', {
Expand All @@ -247,6 +331,7 @@ describe('PUT /users/:id', () => {
expect(user).toEqual({
id: 'abc-123',
firstName: 'Joseph',
lastName: 'White',
})
})

Expand Down Expand Up @@ -276,10 +361,12 @@ describe('PUT /users/:id', () => {
db.user.create({
id: 'abc-123',
firstName: 'John',
lastName: 'White',
})
db.user.create({
id: 'def-456',
firstName: 'Kate',
lastName: 'Moen',
})

const res = await fetch('http://localhost/users/abc-123', {
Expand All @@ -290,6 +377,7 @@ describe('PUT /users/:id', () => {
body: JSON.stringify({
id: 'def-456',
firstName: 'Joseph',
lastName: 'Sipes',
}),
})
const json = await res.json()
Expand All @@ -308,10 +396,12 @@ describe('DELETE /users/:id', () => {
db.user.create({
id: 'abc-123',
firstName: 'John',
lastName: 'White',
})
db.user.create({
id: 'def-456',
firstName: 'Kate',
lastName: 'Moen',
})

const res = await fetch('http://localhost/users/def-456', {
Expand All @@ -322,6 +412,7 @@ describe('DELETE /users/:id', () => {
expect(user).toEqual({
id: 'def-456',
firstName: 'Kate',
lastName: 'Moen',
})

const allUsers = await fetch('http://localhost/users').then((res) =>
Expand All @@ -331,6 +422,7 @@ describe('DELETE /users/:id', () => {
{
id: 'abc-123',
firstName: 'John',
lastName: 'White',
},
])
})
Expand Down

0 comments on commit 035ab01

Please sign in to comment.