Server side pagination in Graphql Scala 在Graphql Scala中的服务器端分页

huangapple go评论83阅读模式
英文:

Server side pagination in Graphql Scala

问题

以下是您提供的内容的翻译:

我需要在Scala中的GraphQL中实现服务器端分页我有七份报告已经使用一个GraphQL查询并使用不同的操作来获取数据现在我需要在其中添加服务器端分页但我无法做到这一点任何帮助都将不胜感激以下是我的代码

Schema模式):
```scala
val PanelNominationStatusReportDataType = ObjectType(
    "PanelNominationStatus",
    "仪表板报告",
    fields[Unit, PanelRewardSatusDetail](
      Field("awardName", OptionType(StringType), resolve = _.value.awardName),
      Field("nominatorEmail", OptionType(StringType), resolve = _.value.nominatorEmail),
      Field("nomineeEmail", OptionType(StringType), resolve = _.value.nomineeEmail),
      Field("nomineeLocation", OptionType(StringType), resolve = _.value.nomineeLocation),
      Field("approverEmail", OptionType(StringType), resolve = _.value.approverEmail),
      Field("citation", OptionType(StringType), resolve = _.value.citation),
      Field("businessJustification", OptionType(StringType), resolve = _.value.businessJustification),
      Field("rating", OptionType(IntType), resolve = _.value.rating),
      Field("votingStatus", OptionType(StringType), resolve = _.value.votingStatus),
      Field("nominatedDate", OptionType(StringType), resolve = _.value.nominatedDate),
      Field("approvedDate", OptionType(StringType), resolve = _.value.approvedDate)
    )
  )

GraphQL查询:

Field(
        "PanelNominationStatus",
        ListType(PanelNominationStatusReportDataType),
        description = Some("返回员工奖励报告数据"),
        arguments = companyIdType :: rewardNamesType :: startDateType :: endDateType :: Nil,
        resolve = { c =>
          c.ctx.getPanelStatusReport(c.arg(companyIdType), c.arg(startDateType), c.arg(endDateType), c.arg(rewardNamesType))
        })

DataRepo(数据仓库):

def getPanelStatusReport(companyId: Int, startDate: Long, endDate: Long, rewardNames: Seq[String]): List[PanelRewardSatusDetail] = {
    val redemptionReport = Await.result(reportsModel.findPanelRewardStatusDetailsReport(companyId, rewardNames, startDate, endDate), 20.seconds).toList
    redemptionReport
  }

最后的模型(Model):

def findPanelRewardStatusDetailsReport(companyId: Int, rewardNames: Seq[String], startDate: Long, endDate: Long): Future[Seq[PanelRewardSatusDetail]] = {
    val df = new SimpleDateFormat("dd-MM-yyyy")
    val start = stringToDateTime(df.format(startDate * 1000L), None).toDateTime()
    val end = stringToDateTime(df.format(endDate * 1000L), None).toDateTime()
    val rewardFilter = if(rewardNames.nonEmpty) s"AND vrrc.reward_name IN (${rewardNames.map(a => s"'$a'").mkString(",")})" else ""
    implicit val getOrdersResult = GetResult(r => PanelRewardSatusDetail(r.<<, r.<<, r.<<, r.<<, r.<<, r.<<, r.<<, r.<<, r.<<, r.<<, r.<<))
    val q = sql"""select vrrc.reward_name, (select login from users where id=vrur.sender_id), (select login from users where id=vrur.receiver_ids), (select city_name from cities where id=(select city_id from users where id=vrur.receiver_ids)), (select login from users where id=approver_user_id), vrur.comment, vrur.business_justification, vrpa.rating, CASE WHEN vrpa.is_approved = 1 THEN 'VOTED' ELSE 'NOT VOTED' END, date(vrpa.created_at), date(vrpa.approved_at) from vr_panel_approval vrpa inner join vr_user_reward vrur on vrur.id=vrpa.user_reward_id inner join vr_reward_config vrrc on vrrc.id=vrur.reward_config_id where vrrc.company_id = $companyId and date(vrpa.created_at) between date($start) and date($end) #$rewardFilter"""
    db.run(q.as[PanelRewardSatusDetail])
  }

我的请求查询(Request Query):

{
	"query": "query PanelNominationStatus($startDate: Long!, $endDate: Long!, $companyId: Int!, $rewardNames: [String!]!) { PanelNominationStatus( startDate: $startDate, endDate: $endDate, companyId: $companyId, rewardNames: $rewardNames ) { awardName nominatorEmail nomineeEmail nomineeLocation approverEmail citation businessJustification rating votingStatus nominatedDate approvedDate }}",
    "operationName": "PanelNominationStatus",
    "variables": {
    	"startDate": 1285891200,
        "endDate": 1576108800,
        "companyId": 355,
        "rewardNames": ["PANEL AWARD FEBRUARY", "PANEL AWARD MARCH"]
    }
}

我可以使用查询中的限制(limit)来实现分页,并在查询中接受它,但我需要在响应中发送总行数,但我无法弄清楚在模式中进行哪些更改。


<details>
<summary>英文:</summary>
I need to do server side pagination in graphql in scala. I have seven reports and have used one graphql query with different operations to get the data. Now I need to add server side pagination to it and I am not able to do that. Any help would be appreciated. Below are my code:
Schema:

val PanelNominationStatusReportDataType = ObjectType(
"PanelNominationStatus",
"Dashboard Reports",
fields[Unit, PanelRewardSatusDetail](
Field("awardName", OptionType(StringType), resolve = _.value.awardName),
Field("nominatorEmail", OptionType(StringType), resolve = _.value.nominatorEmail),
Field("nomineeEmail", OptionType(StringType), resolve = _.value.nomineeEmail),
Field("nomineeLocation", OptionType(StringType), resolve = _.value.nomineeLocation),
Field("approverEmail", OptionType(StringType), resolve = _.value.approverEmail),
Field("citation", OptionType(StringType), resolve = _.value.citation),
Field("businessJustification", OptionType(StringType), resolve = _.value.businessJustification),
Field("rating", OptionType(IntType), resolve = _.value.rating),
Field("votingStatus", OptionType(StringType), resolve = _.value.votingStatus),
Field("nominatedDate", OptionType(StringType), resolve = _.value.nominatedDate),
Field("approvedDate", OptionType(StringType), resolve = _.value.approvedDate)
)
)


Graphql Query:

Field(
"PanelNominationStatus",
ListType(PanelNominationStatusReportDataType),
description = Some("Returns the Employee Reward Report Data"),
arguments = companyIdType :: rewardNamesType :: startDateType :: endDateType :: Nil,
resolve = { c =>
c.ctx.getPanelStatusReport(c.arg(companyIdType), c.arg(startDateType), c.arg(endDateType), c.arg(rewardNamesType))
})


DataRepo:

def getPanelStatusReport(companyId: Int, startDate: Long, endDate: Long, rewardNames: Seq[String]): List[PanelRewardSatusDetail] = {
val redemptionReport = Await.result(reportsModel.findPanelRewardStatusDetailsReport(companyId, rewardNames, startDate, endDate), 20.seconds).toList
redemptionReport
}


And at last the model:

def findPanelRewardStatusDetailsReport(companyId: Int, rewardNames: Seq[String], startDate: Long, endDate: Long): Future[Seq[PanelRewardSatusDetail]] = {
val df = new SimpleDateFormat("dd-MM-yyyy")
val start = stringToDateTime(df.format(startDate * 1000L), None).toDateTime()
val end = stringToDateTime(df.format(endDate * 1000L), None).toDateTime()
val rewardFilter = if(rewardNames.nonEmpty) "AND vrrc.reward_name IN (" + rewardNames.map(a => "'" + a + "'").mkString(",") + ")" else ""
implicit val getOrdersResult = GetResult(r => PanelRewardSatusDetail(r.<<, r.<<, r.<<, r.<<, r.<<, r.<<, r.<<, r.<<, r.<<, r.<<, r.<<))
val q = sql"""select vrrc.reward_name, (select login from users where id=vrur.sender_id), (select login from users where id=vrur.receiver_ids), (select city_name from cities where id=(select city_id from users where id=vrur.receiver_ids)), (select login from users where id=approver_user_id), vrur.comment, vrur.business_justification, vrpa.rating, CASE WHEN vrpa.is_approved = 1 THEN 'VOTED' ELSE 'NOT VOTED' END, date(vrpa.created_at), date(vrpa.approved_at) from vr_panel_approval vrpa inner join vr_user_reward vrur on vrur.id=vrpa.user_reward_id inner join vr_reward_config vrrc on vrrc.id=vrur.reward_config_id where vrrc.company_id = $companyId and date(vrpa.created_at) between date($start) and date($end) #$rewardFilter"""
db.run(q.as[PanelRewardSatusDetail])
}


My request query:

{
"query": "query PanelNominationStatus($startDate: Long!, $endDate: Long!, $companyId: Int!, $rewardNames: [String!]!) { PanelNominationStatus( startDate: $startDate, endDate: $endDate, companyId: $companyId, rewardNames: $rewardNames ) { awardName nominatorEmail nomineeEmail nomineeLocation approverEmail citation businessJustification rating votingStatus nominatedDate approvedDate }}",
"operationName": "PanelNominationStatus",
"variables": {
"startDate": 1285891200,
"endDate": 1576108800,
"companyId": 355,
"rewardNames": ["PANEL AWARD FEBRUARY", "PANEL AWARD MARCH"]
}
}


I can make it possible using limit in the query and accepting it in the query but I need to send the total count of rows in the response as well. But I am not able to figure out where to make change in schema.
</details>
# 答案1
**得分**: 2
You just need to define another GraphQL type for your result which also contains the count,
```scala
val PanelNominationStatusResultType = ObjectType(
"PanelNominationStatusResult",
"Dashboard Reports",
fields[Unit, List[PanelRewardSatusDetail]](
Field(
"count",
IntType,
description = Some("count of nomination-status-reports in this response"),
resolve = _.value.length
),
Field(
"panelNominationStatusList",
ListType(PanelNominationStatusReportDataType),
description = Some("list of nomination-status-reports"),
resolve = _.value
)
)
)

Now, as for your query,

Field(
  "panelNominationStatusResult",
  PanelNominationStatusResultType,
  description = Some("Returns the details of ............"),
  arguments = companyIdType :: rewardNamesType :: startDateType :: endDateType :: Nil,
  resolve = { c =>
      c.ctx.getPanelStatusReport(c.arg(companyIdType), c.arg(startDateType), c.arg(endDateType), c.arg(rewardNamesType))
    }
)

If you want the totalCount, then first of all you need to change your getPanelStatusReport method to also return the totalCount

def findPanelRewardStatusDetailsReport(
  companyId: Int,
  rewardNames: Seq[String],
  startDate: Long,
  endDate: Long
): Future[(Int, Seq[PanelRewardSatusDetail])] = ???

// updated result type
val PanelNominationStatusResultType = ObjectType(
  "PanelNominationStatusResult",
  "Dashboard Reports",
  fields[Unit, (Int, List[PanelRewardSatusDetail])](
    Field(
      "totalCount",
      IntType,
      description = Some("total count of nomination-status-reports"),
      resolve = _.value._1
    ),
    Field(
      "count",
      IntType,
      description = Some("count of nomination-status-reports in this response"),
      resolve = _.value._2.length
    ),
    Field(
      "panelNominationStatusList",
      ListType(PanelNominationStatusReportDataType),
      description = Some("list of nomination-status-reports"),
      resolve = _.value._2
    )
  )
)
英文:

You just need to define another GraphQL type for your result which also contains the count,

val PanelNominationStatusResultType = ObjectType(
&quot;PanelNominationStatusResult&quot;,
&quot;Dashboard Reports&quot;,
fields[Unit, List[PanelRewardSatusDetail]](
Field(
&quot;count&quot;,
IntType,
description = Some(&quot;count of nomination-status-reports in this response&quot;),
resolve = _.value.length
),
Field(
&quot;panelNominationStatusList&quot;,
ListType(PanelNominationStatusReportDataType),
description = Some(&quot;list of nomination-status-reports&quot;),
resolve = _.value
)
)
)

Now, as for your query,

Field(
&quot;panelNominationStatusResult&quot;,
PanelNominationStatusResultType,
description = Some(&quot;Returns the details of ............&quot;),
arguments = companyIdType :: rewardNamesType :: startDateType :: endDateType :: Nil,
resolve = { c =&gt;
c.ctx.getPanelStatusReport(c.arg(companyIdType), c.arg(startDateType), c.arg(endDateType), c.arg(rewardNamesType))
}
)

If you want the totalCount, then first of all you need to change your getPanelStatusReport method to also return the totalCount

def findPanelRewardStatusDetailsReport(
companyId: Int,
rewardNames: Seq[String],
startDate: Long,
endDate: Long
): Future[(Int, Seq[PanelRewardSatusDetail])] = ???
// updated result type
val PanelNominationStatusResultType = ObjectType(
&quot;PanelNominationStatusResult&quot;,
&quot;Dashboard Reports&quot;,
fields[Unit, (Int, List[PanelRewardSatusDetail])](
Field(
&quot;totalCount&quot;,
IntType,
description = Some(&quot;total count of nomination-status-reports&quot;),
resolve = _.value._1
),
Field(
&quot;count&quot;,
IntType,
description = Some(&quot;count of nomination-status-reports in this response&quot;),
resolve = _.value._2.length
),
Field(
&quot;panelNominationStatusList&quot;,
ListType(PanelNominationStatusReportDataType),
description = Some(&quot;list of nomination-status-reports&quot;),
resolve = _.value._2
)
)
)

huangapple
  • 本文由 发表于 2020年1月3日 23:47:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/59581433.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定