Skip to content

Commit

Permalink
REST API: paginate project task list (#3659)
Browse files Browse the repository at this point in the history
* REST API: paginate project task list

* scalafmt

* changelog

* rest api docs
  • Loading branch information
fm3 authored Jan 24, 2019
1 parent 0bd7c7b commit b254d98
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 13 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ For upgrade instructions, please check the [migration guide](MIGRATIONS.md).
### Added

- Added the possibility to disable that the current layout is saved automatically when changing it. Instead, the layout can be saved explicitly. [#3620](https://github.com/scalableminds/webknossos/pull/3620)
- Added pagination to the REST API route `GET /projects/:name/tasks` (new optional parameters `limit` and `pageNumber`). [#3659](https://github.com/scalableminds/webknossos/pull/3659)
- Added the possibility to open the version restore view for read-only tracings. Older versions can be previewed and be downloaded as NML. [#3660](https://github.com/scalableminds/webknossos/pull/3660)

### Changed
Expand Down
20 changes: 11 additions & 9 deletions app/controllers/ProjectController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -119,16 +119,18 @@ class ProjectController @Inject()(projectService: ProjectService,
Ok(js)
}

def tasksForProject(projectName: String) = sil.SecuredAction.async { implicit request =>
for {
project <- projectDAO.findOneByName(projectName) ?~> Messages("project.notFound", projectName)
_ <- Fox.assertTrue(userService.isTeamManagerOrAdminOf(request.identity, project._team)) ?~> "notAllowed"
tasks <- taskDAO.findAllByProject(project._id)(GlobalAccessContext)
js <- Fox.serialCombined(tasks)(task => taskService.publicWrites(task))
} yield {
Ok(Json.toJson(js))
def tasksForProject(projectName: String, limit: Option[Int] = None, pageNumber: Option[Int] = None) =
sil.SecuredAction.async { implicit request =>
for {
project <- projectDAO.findOneByName(projectName) ?~> Messages("project.notFound", projectName)
_ <- Fox.assertTrue(userService.isTeamManagerOrAdminOf(request.identity, project._team)) ?~> "notAllowed"
tasks <- taskDAO.findAllByProject(project._id, limit.getOrElse(Int.MaxValue), pageNumber.getOrElse(0))(
GlobalAccessContext)
js <- Fox.serialCombined(tasks)(task => taskService.publicWrites(task))
} yield {
Ok(Json.toJson(js))
}
}
}

def incrementEachTasksInstances(projectName: String, delta: Option[Long]) = sil.SecuredAction.async {
implicit request =>
Expand Down
7 changes: 4 additions & 3 deletions app/models/task/Task.scala
Original file line number Diff line number Diff line change
Expand Up @@ -156,12 +156,13 @@ class TaskDAO @Inject()(sqlClient: SQLClient, projectDAO: ProjectDAO)(implicit e
parsed <- Fox.combined(r.toList.map(parse))
} yield parsed

def findAllByProject(projectId: ObjectId)(implicit ctx: DBAccessContext): Fox[List[Task]] =
def findAllByProject(projectId: ObjectId, limit: Int, pageNumber: Int)(
implicit ctx: DBAccessContext): Fox[List[Task]] =
for {
accessQuery <- readAccessQuery
r <- run(
sql"select #${columns} from #${existingCollectionName} where _project = ${projectId.id} and #${accessQuery}"
.as[TasksRow])
sql"""select #${columns} from #${existingCollectionName} where _project = ${projectId.id} and #${accessQuery}
order by _id desc limit ${limit} offset ${pageNumber * limit}""".as[TasksRow])
parsed <- Fox.combined(r.toList.map(parse))
} yield parsed

Expand Down
2 changes: 1 addition & 1 deletion conf/webknossos.latest.routes
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ POST /projects
GET /projects/:name controllers.ProjectController.read(name: String)
DELETE /projects/:name controllers.ProjectController.delete(name: String)
PUT /projects/:name controllers.ProjectController.update(name: String)
GET /projects/:name/tasks controllers.ProjectController.tasksForProject(name: String)
GET /projects/:name/tasks controllers.ProjectController.tasksForProject(name: String, limit: Option[Int], pageNumber: Option[Int])
PATCH /projects/:name/incrementEachTasksInstances controllers.ProjectController.incrementEachTasksInstances(name: String, delta: Option[Long])
PATCH /projects/:name/pause controllers.ProjectController.pause(name: String)
PATCH /projects/:name/resume controllers.ProjectController.resume(name: String)
Expand Down
6 changes: 6 additions & 0 deletions docs/rest_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -524,10 +524,16 @@ List all tasks of a project

#### Expects
- In the url: `:name` name of a project
- Optional GET parameter `limit=[INT]`
- return only the first x results (defaults to infinity)
- Optional GET parameter `pageNumber=[INT]`
- return the results starting at offset `limit` * `pageNumber` (defaults to 0)

#### Returns
- JSON list of objects containing task information

#### Note
- For smoother backwards compatibility, the limit defaults to infinity. However, to ease server load and improve response time, we suggest using a limit of 1000


---
Expand Down

0 comments on commit b254d98

Please sign in to comment.