diff --git a/server/app/com/xsn/explorer/errors/paginatedQueryErrors.scala b/server/app/com/xsn/explorer/errors/paginatedQueryErrors.scala new file mode 100644 index 0000000..68b9635 --- /dev/null +++ b/server/app/com/xsn/explorer/errors/paginatedQueryErrors.scala @@ -0,0 +1,22 @@ +package com.xsn.explorer.errors + +import com.alexitc.playsonify.models.{FieldValidationError, InputValidationError, PublicError} +import play.api.i18n.{Lang, MessagesApi} + +sealed trait PaginatedQueryError + +case object PaginatedQueryOffsetError extends PaginatedQueryError with InputValidationError { + override def toPublicErrorList(messagesApi: MessagesApi)(implicit lang: Lang): List[PublicError] = { + val message = messagesApi("error.paginatedQuery.offset") + val error = FieldValidationError("offset", message) + List(error) + } +} + +case class PaginatedQueryLimitError(maxValue: Int) extends PaginatedQueryError with InputValidationError { + override def toPublicErrorList(messagesApi: MessagesApi)(implicit lang: Lang): List[PublicError] = { + val message = messagesApi("error.paginatedQuery.limit", maxValue) + val error = FieldValidationError("limit", message) + List(error) + } +} diff --git a/server/app/com/xsn/explorer/services/validators/PaginatedQueryValidator.scala b/server/app/com/xsn/explorer/services/validators/PaginatedQueryValidator.scala new file mode 100644 index 0000000..afec06b --- /dev/null +++ b/server/app/com/xsn/explorer/services/validators/PaginatedQueryValidator.scala @@ -0,0 +1,37 @@ +package com.xsn.explorer.services.validators + +import com.alexitc.playsonify.core.ApplicationResult +import com.xsn.explorer.errors.{PaginatedQueryLimitError, PaginatedQueryOffsetError} +import com.xsn.explorer.models.base.{Limit, Offset, PaginatedQuery} +import org.scalactic.{Accumulation, Bad, Good} + +class PaginatedQueryValidator { + + private val MinOffset = 0 + private val LimitRange = 1 to 100 + + def validate(query: PaginatedQuery): ApplicationResult[PaginatedQuery] = { + Accumulation.withGood( + validateOffset(query.offset), + validateLimit(query.limit)) { + + PaginatedQuery.apply + } + } + + private def validateOffset(offset: Offset): ApplicationResult[Offset] = { + if (offset.int >= MinOffset) { + Good(offset) + } else { + Bad(PaginatedQueryOffsetError).accumulating + } + } + + private def validateLimit(limit: Limit): ApplicationResult[Limit] = { + if (LimitRange contains limit.int) { + Good(limit) + } else { + Bad(PaginatedQueryLimitError(LimitRange.last)).accumulating + } + } +} diff --git a/server/conf/messages b/server/conf/messages index 873e2d0..2d5e29c 100644 --- a/server/conf/messages +++ b/server/conf/messages @@ -9,3 +9,6 @@ error.address.format=Invalid address format error.block.format=Invalid blockhash format error.block.notFound=Block not found + +error.paginatedQuery.offset.invalid=Invalid offset, it should be a number greater or equal than 0 +error.paginatedQuery.limit.invalid=Invalid limit, it should be a number between 1 and and {0}