Skip to content

Commit

Permalink
Merge pull request #5 from shemaeric/feature/Implement-Pagination-Sor…
Browse files Browse the repository at this point in the history
…ting-and-filtering

Add Filtering, Sorting and Pagination
  • Loading branch information
shemaeric authored Apr 18, 2023
2 parents 0741d74 + 162b981 commit 9f82467
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 23 deletions.
17 changes: 8 additions & 9 deletions src/services/movie.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
import { Movie, MovieQuote } from '../Models/Movie';
import { Base } from '../client/base';
import { RequestQuery } from '../types';
import { resources } from '../utils';
import { formatUrlWithQueries } from '../utils/queryFormat';

export class MovieService extends Base {

public async getMovies(): Promise<Movie[]> {
const movieUrl = `${resources.movie}`;

public async getMovies(query?: RequestQuery): Promise<Movie[]> {
const movieUrl = formatUrlWithQueries(`${resources.movie}`, query);
return await this.invoke(movieUrl);
}

public async getSingleMovie(id: string): Promise<Movie> {
const movieUrl = `${resources.movie}/${id}`;

public async getSingleMovie(id: string, query?: RequestQuery): Promise<Movie> {
const movieUrl = formatUrlWithQueries(`${resources.movie}/${id}`, query);
return await this.invoke(movieUrl);
}

public async getMovieQuote(id: string): Promise<MovieQuote> {
const url = `${resources.movie}/${id}/quote`;

public async getMovieQuote(id: string, query?: RequestQuery): Promise<MovieQuote> {
const url = formatUrlWithQueries(`${resources.movie}/${id}/quote`, query);
return await this.invoke(url);
}
}
30 changes: 16 additions & 14 deletions src/types/requestQuery.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
export interface SortData {
by: string;
direction: 'asc' | 'desc';
}

export interface PaginateData {
offset: number;
limit: number;
page: number;
}

export interface RequestQueryData {
sort?: SortData;
}
export interface RequestQuery {
sort?: { sortBy: string; direction: 'asc' | 'desc' };
paginate?: { option: 'limit' | 'offset' | 'page'; value: number };
filter?: {
match?: { field: string; value: string }[];
negateMatch?: { field: string; value: string }[];
include?: { field: string; value: string[] }[];
exclude?: { field: string; value: string[] }[];
exists?: string[];
doesNotExist?: string[];
lessThan?: { field: string; value: string }[];
greaterThanOrEqual?: { field: string; value: string }[];
greaterThan?: { field: string; value: string }[];
lessThanOrEqual?: { field: string; value: string }[];
};
}
98 changes: 98 additions & 0 deletions src/utils/queryFormat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import { RequestQuery } from "../types";

export function formatUrlWithQueries(source: string, query?: RequestQuery): string {
let url = source;

if (!query) {
return url
}
if (query.sort) {
const { sortBy, direction } = query.sort;
url += `?sort=${sortBy}:${direction}`;
}

if (query.paginate) {
const { option, value } = query.paginate;
url += `?${option}=${value}`;
}

if (query.filter) {
const {
match,
negateMatch,
include,
exclude,
exists,
doesNotExist,
lessThan,
greaterThanOrEqual,
greaterThan,
lessThanOrEqual
} = query.filter;

if (match) {
match.forEach(({ field, value }) => {
url += `?${field}=${value}`;
});
}

if (negateMatch) {
negateMatch.forEach(({ field, value }) => {
url += `?${field}!=${value}`;
});
}

if (include) {
include.forEach(({ field, value }) => {
const joinedValues = value.join(',');
url += `?include=${field}:${joinedValues}`;
});
}

if (exclude) {
exclude.forEach(({ field, value }) => {
const joinedValues = value.join(',');
url += `?exclude=${field}:${joinedValues}`;
});
}

if (exists) {
exists.forEach((field) => {
url += `?${field}`;
});
}

if (doesNotExist) {
doesNotExist.forEach((field) => {
url += `?!${field}`;
});
}

if (lessThan) {
lessThan.forEach(({ field, value }) => {
url += `?${field}<${value}`;
});
}

if (greaterThanOrEqual) {
greaterThanOrEqual.forEach(({ field, value }) => {
url += `?${field}>=${value}`;
});
}

if (greaterThan) {
greaterThan.forEach(({ field, value }) => {
url += `?${field}>${value}`;
});
}

if (lessThanOrEqual) {
lessThanOrEqual.forEach(({ field, value }) => {
url += `?${field}<=${value}`;
});
}
}

return url;
}

0 comments on commit 9f82467

Please sign in to comment.