Skip to content

Commit c193422

Browse files
committed
Ensure pagination order is deterministic
1 parent b809a42 commit c193422

File tree

4 files changed

+96
-12
lines changed

4 files changed

+96
-12
lines changed

api/controllers/course.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,10 @@ func CourseAll(c *gin.Context) {
139139

140140
// @Id courseSectionSearch
141141
// @Router /course/sections [get]
142-
// @Description "Returns all the sections of all the courses matching the query's string-typed key-value pairs"
142+
// @Description "Returns paginated list of sections of all the courses matching the query's string-typed key-value pairs. See former_offset and latter_offset for pagination details."
143143
// @Produce json
144+
// @Param former_offset query number false "The starting position of the current page of courses (e.g. For starting at the 17th course, former_offset=16)."
145+
// @Param latter_offset query number false "The starting position of the current page of sections (e.g. For starting at the 4th section, latter_offset=3)."
144146
// @Param course_number query string false "The course's official number"
145147
// @Param subject_prefix query string false "The course's subject prefix"
146148
// @Param title query string false "The course's title"
@@ -243,6 +245,9 @@ func courseSection(flag string, c *gin.Context) {
243245
// replace the courses with sections
244246
bson.D{{Key: "$replaceWith", Value: "$sections"}},
245247

248+
// keep order deterministic between calls
249+
bson.D{{Key: "$sort", Value: bson.D{{Key: "_id", Value: 1}}}},
250+
246251
// paginate the sections
247252
bson.D{{Key: "$skip", Value: paginateMap["latter_offset"]}},
248253
bson.D{{Key: "$limit", Value: paginateMap["limit"]}},

api/controllers/professor.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,10 @@ func ProfessorAll(c *gin.Context) {
148148

149149
// @Id professorCourseSearch
150150
// @Router /professor/courses [get]
151-
// @Description "Returns all of the courses of all the professors matching the query's string-typed key-value pairs"
151+
// @Description "Returns paginated list of the courses of all the professors matching the query's string-typed key-value pairs. See former_offset and latter_offset for pagination details."
152152
// @Produce json
153+
// @Param former_offset query number false "The starting position of the current page of professors (e.g. For starting at the 17th professor, former_offset=16)."
154+
// @Param latter_offset query number false "The starting position of the current page of courses (e.g. For starting at the 4th course, latter_offset=3)."
153155
// @Param first_name query string false "The professor's first name"
154156
// @Param last_name query string false "The professor's last name"
155157
// @Param titles query string false "One of the professor's title"
@@ -252,6 +254,9 @@ func professorCourse(flag string, c *gin.Context) {
252254
// replace the combination of ids and courses with the courses entirely
253255
bson.D{{Key: "$replaceWith", Value: "$courses"}},
254256

257+
// keep order deterministic between calls
258+
bson.D{{Key: "$sort", Value: bson.D{{Key: "_id", Value: 1}}}},
259+
255260
// paginate the courses
256261
bson.D{{Key: "$skip", Value: paginateMap["latter_offset"]}},
257262
bson.D{{Key: "$limit", Value: paginateMap["limit"]}},
@@ -275,8 +280,10 @@ func professorCourse(flag string, c *gin.Context) {
275280

276281
// @Id professorSectionSearch
277282
// @Router /professor/sections [get]
278-
// @Description "Returns all of the sections of all the professors matching the query's string-typed key-value pairs"
283+
// @Description "Returns paginated list of the sections of all the professors matching the query's string-typed key-value pairs. See former_offset and latter_offset for pagination details."
279284
// @Produce json
285+
// @Param former_offset query number false "The starting position of the current page of professors (e.g. For starting at the 17th professor, former_offset=16)."
286+
// @Param latter_offset query number false "The starting position of the current page of sections (e.g. For starting at the 4th section, latter_offset=3)."
280287
// @Param first_name query string false "The professor's first name"
281288
// @Param last_name query string false "The professor's last name"
282289
// @Param titles query string false "One of the professor's title"
@@ -368,6 +375,9 @@ func professorSection(flag string, c *gin.Context) {
368375
// replace the combination of ids and sections with the sections entirely
369376
bson.D{{Key: "$replaceWith", Value: "$sections"}},
370377

378+
// keep order deterministic between calls
379+
bson.D{{Key: "$sort", Value: bson.D{{Key: "_id", Value: 1}}}},
380+
371381
// paginate the sections
372382
bson.D{{Key: "$skip", Value: paginateMap["latter_offset"]}},
373383
bson.D{{Key: "$limit", Value: paginateMap["limit"]}},

api/docs/docs.go

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -166,12 +166,24 @@ const docTemplate = `{
166166
},
167167
"/course/sections": {
168168
"get": {
169-
"description": "\"Returns all the sections of all the courses matching the query's string-typed key-value pairs\"",
169+
"description": "\"Returns paginated list of sections of all the courses matching the query's string-typed key-value pairs. See former_offset and latter_offset for pagination details.\"",
170170
"produces": [
171171
"application/json"
172172
],
173173
"operationId": "courseSectionSearch",
174174
"parameters": [
175+
{
176+
"type": "number",
177+
"description": "The starting position of the current page of courses (e.g. For starting at the 17th course, former_offset=16).",
178+
"name": "former_offset",
179+
"in": "query"
180+
},
181+
{
182+
"type": "number",
183+
"description": "The starting position of the current page of sections (e.g. For starting at the 4th section, latter_offset=3).",
184+
"name": "latter_offset",
185+
"in": "query"
186+
},
175187
{
176188
"type": "string",
177189
"description": "The course's official number",
@@ -684,12 +696,24 @@ const docTemplate = `{
684696
},
685697
"/professor/courses": {
686698
"get": {
687-
"description": "\"Returns all of the courses of all the professors matching the query's string-typed key-value pairs\"",
699+
"description": "\"Returns paginated list of the courses of all the professors matching the query's string-typed key-value pairs. See former_offset and latter_offset for pagination details.\"",
688700
"produces": [
689701
"application/json"
690702
],
691703
"operationId": "professorCourseSearch",
692704
"parameters": [
705+
{
706+
"type": "number",
707+
"description": "The starting position of the current page of professors (e.g. For starting at the 17th professor, former_offset=16).",
708+
"name": "former_offset",
709+
"in": "query"
710+
},
711+
{
712+
"type": "number",
713+
"description": "The starting position of the current page of courses (e.g. For starting at the 4th course, latter_offset=3).",
714+
"name": "latter_offset",
715+
"in": "query"
716+
},
693717
{
694718
"type": "string",
695719
"description": "The professor's first name",
@@ -826,12 +850,24 @@ const docTemplate = `{
826850
},
827851
"/professor/sections": {
828852
"get": {
829-
"description": "\"Returns all of the sections of all the professors matching the query's string-typed key-value pairs\"",
853+
"description": "\"Returns paginated list of the sections of all the professors matching the query's string-typed key-value pairs. See former_offset and latter_offset for pagination details.\"",
830854
"produces": [
831855
"application/json"
832856
],
833857
"operationId": "professorSectionSearch",
834858
"parameters": [
859+
{
860+
"type": "number",
861+
"description": "The starting position of the current page of professors (e.g. For starting at the 17th professor, former_offset=16).",
862+
"name": "former_offset",
863+
"in": "query"
864+
},
865+
{
866+
"type": "number",
867+
"description": "The starting position of the current page of sections (e.g. For starting at the 4th section, latter_offset=3).",
868+
"name": "latter_offset",
869+
"in": "query"
870+
},
835871
{
836872
"type": "string",
837873
"description": "The professor's first name",

api/docs/swagger.yaml

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -495,10 +495,21 @@ paths:
495495
type: array
496496
/course/sections:
497497
get:
498-
description: '"Returns all the sections of all the courses matching the query''s
499-
string-typed key-value pairs"'
498+
description: '"Returns paginated list of sections of all the courses matching
499+
the query''s string-typed key-value pairs. See former_offset and latter_offset
500+
for pagination details."'
500501
operationId: courseSectionSearch
501502
parameters:
503+
- description: The starting position of the current page of courses (e.g. For
504+
starting at the 17th course, former_offset=16).
505+
in: query
506+
name: former_offset
507+
type: number
508+
- description: The starting position of the current page of sections (e.g. For
509+
starting at the 4th section, latter_offset=3).
510+
in: query
511+
name: latter_offset
512+
type: number
502513
- description: The course's official number
503514
in: query
504515
name: course_number
@@ -866,10 +877,21 @@ paths:
866877
type: array
867878
/professor/courses:
868879
get:
869-
description: '"Returns all of the courses of all the professors matching the
870-
query''s string-typed key-value pairs"'
880+
description: '"Returns paginated list of the courses of all the professors matching
881+
the query''s string-typed key-value pairs. See former_offset and latter_offset
882+
for pagination details."'
871883
operationId: professorCourseSearch
872884
parameters:
885+
- description: The starting position of the current page of professors (e.g.
886+
For starting at the 17th professor, former_offset=16).
887+
in: query
888+
name: former_offset
889+
type: number
890+
- description: The starting position of the current page of courses (e.g. For
891+
starting at the 4th course, latter_offset=3).
892+
in: query
893+
name: latter_offset
894+
type: number
873895
- description: The professor's first name
874896
in: query
875897
name: first_name
@@ -964,10 +986,21 @@ paths:
964986
type: array
965987
/professor/sections:
966988
get:
967-
description: '"Returns all of the sections of all the professors matching the
968-
query''s string-typed key-value pairs"'
989+
description: '"Returns paginated list of the sections of all the professors
990+
matching the query''s string-typed key-value pairs. See former_offset and
991+
latter_offset for pagination details."'
969992
operationId: professorSectionSearch
970993
parameters:
994+
- description: The starting position of the current page of professors (e.g.
995+
For starting at the 17th professor, former_offset=16).
996+
in: query
997+
name: former_offset
998+
type: number
999+
- description: The starting position of the current page of sections (e.g. For
1000+
starting at the 4th section, latter_offset=3).
1001+
in: query
1002+
name: latter_offset
1003+
type: number
9711004
- description: The professor's first name
9721005
in: query
9731006
name: first_name

0 commit comments

Comments
 (0)