Skip to content

Commit 5074e5b

Browse files
committed
refactor: simplify API routes registration
1 parent ec75911 commit 5074e5b

3 files changed

Lines changed: 106 additions & 150 deletions

File tree

acidify-milky/src/commonMain/kotlin/org/ntqqrev/acidify/milky/api/HttpRoutes.kt

Lines changed: 85 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import io.ktor.server.plugins.di.*
55
import io.ktor.server.request.*
66
import io.ktor.server.response.*
77
import io.ktor.server.routing.*
8+
import kotlinx.serialization.json.JsonElement
9+
import kotlinx.serialization.json.decodeFromJsonElement
810
import kotlinx.serialization.json.encodeToJsonElement
911
import org.ntqqrev.acidify.AbstractBot
1012
import org.ntqqrev.acidify.exception.OidbException
@@ -21,19 +23,22 @@ import kotlin.time.measureTime
2123

2224
inline fun <reified T : Any, reified R : Any> ApiEndpoint<T, R>.define(
2325
noinline handler: suspend context(MediaSourceScope) MilkyContext.(T) -> R
24-
) = MilkyApiHandler(this.path, handler)
26+
) = MilkyApiHandler(
27+
path = this.path,
28+
transformInput = milkyJsonModule::decodeFromJsonElement,
29+
transformOutput = milkyJsonModule::encodeToJsonElement,
30+
callHandler = handler,
31+
)
2532

2633
context(ctx: MilkyContext)
27-
private inline fun <reified T : Any, reified R : Any> Route.serve(
28-
handler: MilkyApiHandler<T, R>
29-
) = post(handler.path) {
34+
private fun <T : Any, R : Any> Route.serve(handler: MilkyApiHandler<T, R>) = post(handler.path) {
3035
val bot = application.dependencies.resolve<AbstractBot>()
3136
val logger = bot.createLogger("HttpModule")
3237
try {
33-
val payload = call.receive<T>()
38+
val rawPayload = call.receive<JsonElement>()
3439
call.respond(
3540
try {
36-
var result: R
41+
var result: JsonElement
3742
val duration = measureTime {
3843
result = mediaSourceScoped(
3944
onDisposeFailure = { source, exception ->
@@ -42,7 +47,7 @@ private inline fun <reified T : Any, reified R : Any> Route.serve(
4247
}
4348
}
4449
) {
45-
handler.callHandler(ctx, payload)
50+
handler.handleRaw(rawPayload)
4651
}
4752
}
4853
logger.i {
@@ -55,7 +60,7 @@ private inline fun <reified T : Any, reified R : Any> Route.serve(
5560
ApiGeneralResponse(
5661
status = "ok",
5762
retcode = 0,
58-
data = milkyJsonModule.encodeToJsonElement(result)
63+
data = result,
5964
)
6065
} catch (e: MilkyApiException) {
6166
logger.w { "${call.request.local.remoteAddress} 调用 API ${handler.path}${e.retcode} ${e.message}" }
@@ -109,74 +114,80 @@ private inline fun <reified T : Any, reified R : Any> Route.serve(
109114
}
110115
}
111116

112-
context(ctx: MilkyContext)
113-
fun Route.apiRoutes() {
114-
serve(GetLoginInfo)
115-
serve(GetImplInfo)
116-
serve(GetUserProfile)
117-
serve(GetFriendList)
118-
serve(GetFriendInfo)
119-
serve(GetGroupList)
120-
serve(GetGroupInfo)
121-
serve(GetGroupMemberList)
122-
serve(GetGroupMemberInfo)
123-
serve(GetPeerPins)
124-
serve(SetPeerPin)
125-
serve(SetAvatar)
126-
serve(SetNickname)
127-
serve(SetBio)
128-
serve(GetCustomFaceUrlList)
129-
serve(GetCookies)
130-
serve(GetCsrfToken)
117+
val apiHandlers = listOf(
118+
GetLoginInfo,
119+
GetImplInfo,
120+
GetUserProfile,
121+
GetFriendList,
122+
GetFriendInfo,
123+
GetGroupList,
124+
GetGroupInfo,
125+
GetGroupMemberList,
126+
GetGroupMemberInfo,
127+
GetPeerPins,
128+
SetPeerPin,
129+
SetAvatar,
130+
SetNickname,
131+
SetBio,
132+
GetCustomFaceUrlList,
133+
GetCookies,
134+
GetCsrfToken,
135+
136+
SendPrivateMessage,
137+
SendGroupMessage,
138+
RecallPrivateMessage,
139+
RecallGroupMessage,
140+
GetMessage,
141+
GetHistoryMessages,
142+
GetResourceTempUrl,
143+
GetForwardedMessages,
144+
MarkMessageAsRead,
131145

132-
serve(SendPrivateMessage)
133-
serve(SendGroupMessage)
134-
serve(RecallPrivateMessage)
135-
serve(RecallGroupMessage)
136-
serve(GetMessage)
137-
serve(GetHistoryMessages)
138-
serve(GetResourceTempUrl)
139-
serve(GetForwardedMessages)
140-
serve(MarkMessageAsRead)
146+
SendFriendNudge,
147+
SendProfileLike,
148+
DeleteFriend,
149+
GetFriendRequests,
150+
AcceptFriendRequest,
151+
RejectFriendRequest,
141152

142-
serve(SendFriendNudge)
143-
serve(SendProfileLike)
144-
serve(DeleteFriend)
145-
serve(GetFriendRequests)
146-
serve(AcceptFriendRequest)
147-
serve(RejectFriendRequest)
153+
SetGroupName,
154+
SetGroupAvatar,
155+
SetGroupMemberCard,
156+
SetGroupMemberSpecialTitle,
157+
SetGroupMemberAdmin,
158+
SetGroupMemberMute,
159+
SetGroupWholeMute,
160+
KickGroupMember,
161+
GetGroupAnnouncements,
162+
SendGroupAnnouncement,
163+
DeleteGroupAnnouncement,
164+
GetGroupEssenceMessages,
165+
SetGroupEssenceMessage,
166+
QuitGroup,
167+
SendGroupMessageReaction,
168+
SendGroupNudge,
169+
GetGroupNotifications,
170+
AcceptGroupRequest,
171+
RejectGroupRequest,
172+
AcceptGroupInvitation,
173+
RejectGroupInvitation,
148174

149-
serve(SetGroupName)
150-
serve(SetGroupAvatar)
151-
serve(SetGroupMemberCard)
152-
serve(SetGroupMemberSpecialTitle)
153-
serve(SetGroupMemberAdmin)
154-
serve(SetGroupMemberMute)
155-
serve(SetGroupWholeMute)
156-
serve(KickGroupMember)
157-
serve(GetGroupAnnouncements)
158-
serve(SendGroupAnnouncement)
159-
serve(DeleteGroupAnnouncement)
160-
serve(GetGroupEssenceMessages)
161-
serve(SetGroupEssenceMessage)
162-
serve(QuitGroup)
163-
serve(SendGroupMessageReaction)
164-
serve(SendGroupNudge)
165-
serve(GetGroupNotifications)
166-
serve(AcceptGroupRequest)
167-
serve(RejectGroupRequest)
168-
serve(AcceptGroupInvitation)
169-
serve(RejectGroupInvitation)
175+
UploadPrivateFile,
176+
UploadGroupFile,
177+
GetPrivateFileDownloadUrl,
178+
GetGroupFileDownloadUrl,
179+
GetGroupFiles,
180+
MoveGroupFile,
181+
RenameGroupFile,
182+
DeleteGroupFile,
183+
CreateGroupFolder,
184+
RenameGroupFolder,
185+
DeleteGroupFolder,
186+
)
170187

171-
serve(UploadPrivateFile)
172-
serve(UploadGroupFile)
173-
serve(GetPrivateFileDownloadUrl)
174-
serve(GetGroupFileDownloadUrl)
175-
serve(GetGroupFiles)
176-
serve(MoveGroupFile)
177-
serve(RenameGroupFile)
178-
serve(DeleteGroupFile)
179-
serve(CreateGroupFolder)
180-
serve(RenameGroupFolder)
181-
serve(DeleteGroupFolder)
188+
context(ctx: MilkyContext)
189+
fun Route.apiRoutes() {
190+
apiHandlers.forEach {
191+
serve(it)
192+
}
182193
}
Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,19 @@
11
package org.ntqqrev.acidify.milky.api
22

3+
import kotlinx.serialization.json.JsonElement
34
import org.ntqqrev.acidify.milky.MediaSourceScope
45
import org.ntqqrev.acidify.milky.MilkyContext
56

67
class MilkyApiHandler<T : Any, R : Any>(
78
val path: String,
9+
val transformInput: (JsonElement) -> T,
10+
val transformOutput: (R) -> JsonElement,
811
val callHandler: suspend context(MediaSourceScope) MilkyContext.(payload: T) -> R,
9-
)
12+
) {
13+
context(ctx: MilkyContext, _: MediaSourceScope)
14+
suspend fun handleRaw(input: JsonElement): JsonElement {
15+
val payload = transformInput(input)
16+
val result = callHandler(ctx, payload)
17+
return transformOutput(result)
18+
}
19+
}

yogurt/src/commonMain/kotlin/org/ntqqrev/yogurt/scripting/Configure.kt

Lines changed: 10 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ import com.dokar.quickjs.binding.define
66
import io.ktor.server.application.*
77
import io.ktor.server.plugins.di.*
88
import kotlinx.coroutines.*
9+
import kotlinx.serialization.json.Json
10+
import kotlinx.serialization.json.JsonElement
911
import org.ntqqrev.acidify.AbstractBot
1012
import org.ntqqrev.acidify.milky.MilkyContext
1113
import org.ntqqrev.acidify.milky.api.MilkyApiHandler
12-
import org.ntqqrev.acidify.milky.api.handler.*
14+
import org.ntqqrev.acidify.milky.api.apiHandlers
1315
import org.ntqqrev.acidify.milky.mediaSourceScoped
1416
import org.ntqqrev.ktfs.withFs
1517
import org.ntqqrev.milky.milkyJsonModule
@@ -48,74 +50,9 @@ suspend fun Application.configureScripting() = QuickJs.create(jobDispatcher = Di
4850

4951
define(internalApiHandle) {
5052
context(this@apply, this) {
51-
defineJsApi(GetLoginInfo)
52-
defineJsApi(GetImplInfo)
53-
defineJsApi(GetUserProfile)
54-
defineJsApi(GetFriendList)
55-
defineJsApi(GetFriendInfo)
56-
defineJsApi(GetGroupList)
57-
defineJsApi(GetGroupInfo)
58-
defineJsApi(GetGroupMemberList)
59-
defineJsApi(GetGroupMemberInfo)
60-
defineJsApi(GetPeerPins)
61-
defineJsApi(SetPeerPin)
62-
defineJsApi(SetAvatar)
63-
defineJsApi(SetNickname)
64-
defineJsApi(SetBio)
65-
defineJsApi(GetCustomFaceUrlList)
66-
defineJsApi(GetCookies)
67-
defineJsApi(GetCsrfToken)
68-
69-
defineJsApi(SendPrivateMessage)
70-
defineJsApi(SendGroupMessage)
71-
defineJsApi(RecallPrivateMessage)
72-
defineJsApi(RecallGroupMessage)
73-
defineJsApi(GetMessage)
74-
defineJsApi(GetHistoryMessages)
75-
defineJsApi(GetResourceTempUrl)
76-
defineJsApi(GetForwardedMessages)
77-
defineJsApi(MarkMessageAsRead)
78-
79-
defineJsApi(SendFriendNudge)
80-
defineJsApi(SendProfileLike)
81-
defineJsApi(DeleteFriend)
82-
defineJsApi(GetFriendRequests)
83-
defineJsApi(AcceptFriendRequest)
84-
defineJsApi(RejectFriendRequest)
85-
86-
defineJsApi(SetGroupName)
87-
defineJsApi(SetGroupAvatar)
88-
defineJsApi(SetGroupMemberCard)
89-
defineJsApi(SetGroupMemberSpecialTitle)
90-
defineJsApi(SetGroupMemberAdmin)
91-
defineJsApi(SetGroupMemberMute)
92-
defineJsApi(SetGroupWholeMute)
93-
defineJsApi(KickGroupMember)
94-
defineJsApi(GetGroupAnnouncements)
95-
defineJsApi(SendGroupAnnouncement)
96-
defineJsApi(DeleteGroupAnnouncement)
97-
defineJsApi(GetGroupEssenceMessages)
98-
defineJsApi(SetGroupEssenceMessage)
99-
defineJsApi(QuitGroup)
100-
defineJsApi(SendGroupMessageReaction)
101-
defineJsApi(SendGroupNudge)
102-
defineJsApi(GetGroupNotifications)
103-
defineJsApi(AcceptGroupRequest)
104-
defineJsApi(RejectGroupRequest)
105-
defineJsApi(AcceptGroupInvitation)
106-
defineJsApi(RejectGroupInvitation)
107-
108-
defineJsApi(UploadPrivateFile)
109-
defineJsApi(UploadGroupFile)
110-
defineJsApi(GetPrivateFileDownloadUrl)
111-
defineJsApi(GetGroupFileDownloadUrl)
112-
defineJsApi(GetGroupFiles)
113-
defineJsApi(MoveGroupFile)
114-
defineJsApi(RenameGroupFile)
115-
defineJsApi(DeleteGroupFile)
116-
defineJsApi(CreateGroupFolder)
117-
defineJsApi(RenameGroupFolder)
118-
defineJsApi(DeleteGroupFolder)
53+
apiHandlers.forEach {
54+
defineJsApi(it)
55+
}
11956
}
12057
}
12158

@@ -157,9 +94,7 @@ context(
15794
scope: ObjectBindingScope,
15895
ctx: MilkyContext,
15996
)
160-
private inline fun <reified T : Any, reified R : Any> Application.defineJsApi(
161-
handler: MilkyApiHandler<T, R>
162-
) {
97+
private fun <T : Any, R : Any> Application.defineJsApi(handler: MilkyApiHandler<T, R>) {
16398
val methodName = handler.path.removePrefix("/")
16499

165100
runBlocking {
@@ -180,7 +115,7 @@ private inline fun <reified T : Any, reified R : Any> Application.defineJsApi(
180115
?: throw IllegalArgumentException("Expected argument to be a JSON string")
181116
val bot = dependencies.resolve<AbstractBot>()
182117
val logger = bot.createLogger("Scripting")
183-
var resp: R
118+
var resp: JsonElement
184119
try {
185120
val duration = measureTime {
186121
resp = mediaSourceScoped(
@@ -190,13 +125,13 @@ private inline fun <reified T : Any, reified R : Any> Application.defineJsApi(
190125
}
191126
}
192127
) {
193-
handler.callHandler(ctx, milkyJsonModule.decodeFromString(payloadString))
128+
handler.handleRaw(Json.parseToJsonElement(payloadString))
194129
}
195130
}
196131
logger.i {
197132
"脚本调用 API ${handler.path}(成功 ${duration.toString(DurationUnit.MILLISECONDS)}"
198133
}
199-
milkyJsonModule.encodeToString(resp)
134+
Json.encodeToString(resp)
200135
} catch (e: Exception) {
201136
logger.e(e) { "脚本调用 API ${handler.path}(失败 ${e::class.simpleName}" }
202137
throw e

0 commit comments

Comments
 (0)