下面我们去定义添加内容标签用的接口,先定义一下这个接口需要的处理器,打开 post.controller,在这个文件的顶部可以导入点东西,从 post.service 里面,把之前定义的 createPostTag 还有 postHasTag 这两个功能导入进来。在接口处理器里面会用到它们提供的功能。
然后导入 TagModel 它来自上一级目录 tag 里面的 tag.model 模块 ,还需要 tag.service 里的两个东西,一个是 getTagByName,还有一个 createTag ,来自上一级目录 tag 下面的 tag.service。
下面找个地方,定义一下添加内容标签接口需要的处理器。处理器的名字可以是 storePostTag, 在这个函数里面先准备点数据,先从地址参数里,把 postId 解构出来,地址参数都会放在 request.params 里面。在设计添加内容标签接口的时候我们会在接口的地址里面添加这个 postId 参数,它的值应该是一个内容的 id 号。
然后再把 name 从请求的主体里面解构出来,请求的主体数据会在 request.body 里面。 再用 let 声明一个 tag,暂时只设置一下它的类型 TagModel,这个 tag 具体的值可以在后面设置。
下面我们可以先在应用的数据仓库里找一下有没有这个标签,用一组 try,catch,在 try 区块里设置一下上面声明的这个 tag 的值,await 执行 getTagByName ,把标签的名字交给这个函数。
查询的时候出了问题可以在 catch 区块里处理,return next() 带着 error,这样异常会交给应用默认的异常处理器处理。
然后再做一下判断,如果找到了这个标签,就是如果要给内容贴上的标签在数据仓库里是存在的。我们可以继续可以再检查一下这个标签是不是之前已经贴到这个内容上了。
用一组 try,catch ,在 try 里面,声明一个 postTag,它的值等于 await 等待执行 postHasTag 返回的结果。使用这个函数的时候要提供内容的 id 还有标签的 id。 它们的类型都应该是数字,所以如果不是数字要用 parseInt 转换一下。
做一下判断,如果 postTag,就是如果这个内容已经被贴上了这个标签,可以报个错误 return next 带着一个错误,错误信息是 POST_ALREADY_HAS_THIS_TAG,这样这个错误会交给应用默认的异常处理器处理,复制一下这个错误信息。
打开 app/app.middleware,在这里找到 defaultErrorHandler,在默认的异常处理器里面添加一种新的错误情况,如果错误信息是这个 POST_ALREADY_HAS_THIS_TAG ,可以把响应的状态码设置成 400,响应的信息设置成内容已经有这个标签了。
回到 post.controller,继续编辑一下,在这个 catch 区块里,执行 return next() 带着 error 。
然后我们还要继续做一下判断,如果在数据仓库里没找到要给内容贴上的标签我们就得先去创建这个标签。 if ! tag ,里面用一组 try,catch,在 try 里面,声明一个 data ,它的值等于 await,执行 createTag,把一个标签数据交给这个函数,一个对象,里面放一个 name 属性,它的值就是标签的名字。这个 createTag 会把标签数据保存到数据仓库里。
下面可以设置一下 tag 的值,等于一个对象,里面添加一个 id 属性,它的值等于 data 里的 insertId 。
这个 data 是执行 createTag 返回的结果,它的值应该就是执行了 sql 查询之后得到的一个结果,它里面的 insertId 这个属性的值是新创建的数据记录的 id 号。
按住 alt 键,点一下 createTag ,查看一下定义这个函数的地方。
这里我们可以访问 data 的 insertId ,是因为在 createTag 这个函数里面,return 的这个 data 的后面用了一个 as any,意思是让这个 data 的值可以是任意的类型。
如果去掉这个 as any ,你会发现,在这里访问 data.insertId 的时候就会报错,提示 data 上面没有 insertId 这个属性。 所以这里 return data 的时候要加上这个 as any。
在 catch 区块里处理一下错误,return 执行 next() 带着 error ,这里用 return 的意思是不继续干别的事儿了。不然会继续执行这个函数的代码。
确定了要贴在内容上的标签已经存在,并且内容之前没有被贴上这个标签之后,就可以给内容打上这个标签了。用一组 try,catch ,在 try 里面,await 执行 createPostTag 这个函数,使用它的时候要提供 postId 还有 tagId,内容的 ID 就是上面从地址参数里得到的 postId 参数,它的值是字符串,所以这里要做 parseInt 把它转换成数字。第二个参数设置成 tag 里的 id 这个属性。
下面做出一个响应,response,用一下 sendStatus ,状态码是 201 。 在 catch 区块里处理一下发生的错误,return 执行 next ,带着 error。
打开 post.router,在这里可以去定义添加内容标签接口。定义这个接口用一下 router 上的 post 方法,接口地址设置成 /posts/:postId/tag
接口需要验证用户的身份,所以安排一个 authGuard 中间件,接口还需要验证用户是不是拥有这个内容资源,可以用一个 accessControl 中间件,一个选项参数,把 possession 设置成 true。
最后把接口的处理器,设置成 postController 里的 storePostTag 。