使用NGRX-Hateoas(Angular)与Spring Hateoas(HAL)时POST请求Payload为空的问题求助
NGRX-Hateoas(Angular)与Spring Hateoas(HAL)时POST请求Payload为空的问题求助
问题背景
我们后端基于Spring Hateoas(HAL)实现,前端Angular之前手动处理前后端通信一直运行正常。最近打算引入ngrx-hateoas来做超媒体状态管理,一开始觉得方向可行,但现在碰到了棘手的问题:触发登录的POST请求时,发送给后端的Payload始终是空对象{},完全没带上用户名和密码参数。
我的实现代码
1. Store配置
我定义了包含登录VM和超媒体动作的Store:
export const initialLoginVm = { username: "", password: "" } export const AppStore = signalStore( { providedIn: 'root' }, withInitialHypermediaResource('rootApi', initialDynamicResource, "http://localhost:4200/api"), withHypermediaResource('loginVm', initialLoginVm), withHypermediaAction('login'), withHooks({ onInit(store) { store._connectLogin(store.loginVm, 'login'); } }) );
2. 触发登录的前端代码
表单提交时,我先把表单值同步到store的loginVm,再调用登录动作:
const loginData = this.store0.getLoginVmAsPatchable() loginData.username.set(this.loginForm.get('username').value); loginData.password.set(this.loginForm.get('password').value); this.store.login().then( (onfulfilled) => { console.log('onfulfilled', onfulfilled); }, (onrejected) => { console.log('onrejected', onrejected); });
3. 适配HAL格式的MetadataProvider
为了让ngrx-hateoas兼容HAL格式,我实现了自定义的MetadataProvider:
import { MetadataProvider, ResourceAction, ResourceLink, ResourceSocket } from "@angular-architects/ngrx-hateoas"; export const HateoasMetadataProvider: MetadataProvider = { isMetadataKey(keyName: string): boolean { return true; }, linkLookup(resource: unknown, linkName: string): ResourceLink | undefined { return resource['_links']; }, actionLookup(resource: unknown, actionName: string): ResourceAction | undefined { // templates let actionMetadataHref = resource['_links']?.['self']?.['href']; let actionMetadataMethod = resource['_templates']?.['default']?.['method']; if (resource['_embedded']) { actionMetadataHref = resource['_embedded']?.[actionName]?.['_links']?.['self']?.['href']; actionMetadataMethod = resource['_embedded']?.[actionName]?.['_templates']?.['default']?.['method']; } if (actionMetadataHref && actionMetadataMethod) return { href: actionMetadataHref, method: actionMetadataMethod }; else return undefined; }, socketLookup(resource: unknown, socketName: string): ResourceSocket | undefined { return resource['_sockets']; } }
4. 后端返回的HAL格式登录端点信息
后端返回的登录端点HAL结构如下:
{ "_links": { "self": { "href": "http://localhost:4200/api/authn/password" } }, "_templates": { "default": { "method": "POST", "properties": [ { "name": "password", "required": true, "type": "text" }, { "name": "username", "regex": "[0-9]", "required": true, "type": "text" } ] } } }
后端期望接收的请求体格式为:
{ "username": "abc", "password": "pw" }
排查现状
我已经确认表单值确实正确同步到了loginVm的信号中,但就是搞不懂为什么ngrx-hateoas没有把这些值打包成请求Payload。因为相关官方文档和案例很少,也没找到类似问题的解决方案,实在没头绪了。
有没有大佬能给点调试方向或者指出我配置中的问题?
内容来源于stack exchange
相关产品推荐
相关产品推荐

