Koa - 初体验(写个接口)
前言
不会node.js的前端不是一个好前端!
这几年node.js确实是越来越火了,好多公司对node.js都开始有要求。虽说前端不一定要会后端,但想要成为一个优秀的前端,node.js是必经之路。
我对于node.js的第一印象,认为它是一门后端语言,只是前端学习起来成本会更低更好上手。慢慢经过了解后,使用node.js写接口对于前端来说很方便,但不仅限于写接口。在一些大公司里,node.js并不是开发接口的首选目标,而是作为中间层来使用。我们都知道分工合作,让专业的人做更专业的事,工作效率会大大提高。node.js作为中间层的存在,可以让后端更专注于写接口和管理数据。
试想一下,现在由于业务逻辑改变,后端需要对数据接口进行更改,是否会花费时间?如果你会node.js,那么你就可以通过node.js来做数据聚合,从几个接口中拼接数据供前端使用,而不需要为数据结构和数据内容烦恼,并且你不用担心效率,因为node.js天生异步。
包括我们常用的一些脚手架工具也是基于node.js环境搭建,你甚至还可以使用node.js来做数据挖掘,也就是我们所说的爬虫,node.js的应用层面还有很多。以上都是我了解到的一些信息。
目前node.js比较主流框架分为express、koa、egg。koa作为新一代的框架,由开发express的原班人马打造,支持ES7 async/await,抛弃回调函数,在写法上更自然。koa没有绑定任何中间件,关键的设计点是在其低级中间件层中提供高级“语法糖”,koa的体积也因此更小。(中间件在koa中是一个很重要的存在,在后面我会着重去学习它)
接下来,我要开始koa入坑之路。
koa初体验
hello,koa!
安装koa ,npm i koa
创建一个app.js,命令行执行 node app
const Koa = require('koa' );
const app = new Koa(); app.context.msg = 'Hello Koa!'
app.use(async ctx => {
ctx.body = ctx.msg;
}); app.listen( 3000);
app.context 为执行上下文添加属性和方法
app.use 将给定的中间件方法添加到应用程序中
该方法接收ctx和next作为参数,ctx 是执行上下文,里面存储了request和response等信息,还有ctx.body,我们可以通过它来返回数据,next作为函数调用,将执行权交给下一个中间件执行。
这里我先安装个nodemon,因为每次更改文件时,都需要重新执行命令以更新代码,这种重复性的工作就交给模块来处理。
通过 npm i nodemon 安装好后,命令行执行 nodemon app,这样每次更改文件时,nodemon都自动刷新。
Koa-router 路由管理
为了代码的可维护性,减少代码量。使用路由管理显得尤为重要,koa框架也有自己对应的路由管理模块(koa-router),我们可以通过npm 下载使用。
var Koa = require('koa' );
var Router = require('koa-router' ); var app = new Koa();
var router = new Router(); router.get( '/', (ctx, next) => {
ctx.body = 'hello'
});
//使用路由中间件
app
.use(router.routes())
.use(router.allowedMethods()); app.listen( 3000 )
routes 注册使用路由
allowedMethods 处理的业务是当所有路由中间件执行完成之后,若 ctx.status 为空或者404的时候,丰富 response 对象的 header 头,不加问题也不大,官方例子有加上,所以我这里也加了
这时访问3000端口就可以得到ctx.body 返回的内容
get请求
1. 获取接口query参数
通过查询 ctx.request.query 得到get参数, ctx.request.header 得到请求时的头部信息,ctx.request.method 得到请求方法。这样可以对应的来做一些判断,例如请求的参数是否合法,请求方法是否合法。
router.get( '/get', (ctx, next) => {
let id = ctx.request.query.id
ctx.body = {
id,
code: 1
}
});
2. 命名路由 获取参数
router.get( '/get/:id', (ctx, next) => {
let id = ctx.request.params.id
ctx.body = {
id,
code: 1
}
});
例如请求地址为 /get/123,通过 ctx.request.params 获取参数
这写法让我想起了vue-router,设置params可以说是一样了。
post请求
原生获取post请求的参数,需要监听ctx.req的data事件和end事件,分段拼接成完整的字符串,然后还需要切割转码。所以在获取post参数时,我会借助 koa-bodyparser 来减少不必要的操作。
在引入 koa-bodyparser 时,需要注意的是顺序问题,使用 koa-bodyparser 需要放在使用路由之前,这是由于中间件执行顺序的原因(暂且理解为 bodyparser 经过处理,把处理好的值转交到路由)
var bodyParser = require('koa-bodyparser'); app.use(bodyParser()); app
.use(passport.initialize())
.use(passport.session())
借助中间件koa-bodyparser,访问 ctx.request.body 得到post参数
通过 ctx.set 设置返回头,设置多个时可传入对象
router.post('/post', ctx=>{
//设置允许跨域
ctx.set('Access-Control-Allow-Origin','*')
ctx.body = {
code:1,
postParams:ctx.request.body
}
})
路由模块化管理
试想一下,现在文件中写有多个接口,我们在开发和调试起来都会特别麻烦,浪费时间。为了更好的管理接口,现在需要把接口按照功能抽离出来,封装到一个个的JS文件中,并存放到routes文件夹下。
例如,创建 user.js 来存放用户相关的接口
const Router = require('koa-router')
const route = new Router()
const jwt = require('jsonwebtoken') route.get('/getToken', async (ctx)=>{
let {name,id} = ctx.query
if(!name && !id){
ctx.body = {
msg:'不合法',
code:0
}
return
}
//生成token
let token = jwt.sign({name,id},'secret',{ expiresIn: '1h' })
ctx.body = {
token: token,
code:1
}
}) route.get('/getUser', async ctx=>{
let id = ctx.query.id
ctx.body = {
user:ctx.payload,
id,
code:1
}
}) route.get('/getAllUser', async ctx=>{
let type = ctx.query.type
if(type){
ctx.body = {
type,
code:1
}
}else{
ctx.body = {
msg:'缺少参数type',
code:0
}
}
}) module.exports = route
以上代码,将写好的接口暴露出去,供app.js注册使用
app.js代码(部分代码省略)
let urls = fs.readdirSync(__dirname + '/routes')
urls.forEach((element) => {
//routes里的js接口文件
let module = require(__dirname + '/routes/' + element)
//routes里的文件名作为 路由名
router.use('/' + element.replace('.js', ''), module.routes())
}) //使用路由
app.use(router.routes()).use(router.allowedMethods()) app.listen(3000)
以上代码,我大概讲下流程
1. fs文件模块读取routes文件夹目录内容(获得的是一个文件名的数组)
2. 数组遍历,引入接口文件,将文件名作为路由名,注册使用路由
将 user.js 作为例子,user.js 内有一个 getUser 的接口,我访问的api地址为 /user/getUser
头部信息处理
在前后端交互中,头部信息也是很关键的一步,通过对头部信息的配置,可以对请求作出一些限制,或者是一些优化。
这里我会使用 koa2-cors 为例子,来对跨域做cors处理(部分代码省略)。
const cors = require('koa2-cors') app.use(cors({
origin: function(ctx) {
return 'http://127.0.0.1:5500';//cors
},
exposeHeaders: ['WWW-Authenticate', 'Server-Authorization'],
maxAge: 5,
credentials: true,
allowMethods: ['GET', 'POST'],
allowHeaders: ['Content-Type', 'Authorization', 'Accept'],
})) app.use(router.routes()).use(router.allowedMethods()) app.listen(3000)
origin : 接受字符串和函数,这里配置的就是允许跨域的域名,如果允许所有域名跨域可传入 *
allowMethods : 允许请求的方式
allowHeaders : 允许接受的头部信息
其他的配置选项可以在npm上查看:https://www.npmjs.com/package/koa2-cors
写在最后
本文通过路由中间件简单实现接口,模块化管理接口文件,还对接口进行跨域处理。
主要还是玩模块,通过模块可以组合出适合自己业务的系统。
Koa - 初体验(写个接口)的更多相关文章
- MarkDown初体验
初体验 写在前面 一周前第一次听说了MarkDown这个编辑器,通过它知道了LaTex,正好满足了我多年对网上博客里的公式简陋的表达的需求.起初,只是用到了LaTex公式这一个功能 , 对于主要文字的 ...
- Python+Flask+Gunicorn 项目实战(一) 从零开始,写一个Markdown解析器 —— 初体验
(一)前言 在开始学习之前,你需要确保你对Python, JavaScript, HTML, Markdown语法有非常基础的了解.项目的源码你可以在 https://github.com/zhu-y ...
- #使用abp框架与vue一步一步写我是月老的小工具(2) 后台搭建初体验
#使用abp框架与vue一步一步写我是月老的小工具(2) 后台搭建初体验 一.续上前言 关于这个小玩意的产品思考,假设我暂时把他叫我是月老热心人 这是一个没有中心的关系链,每个人进入以后都是以自己为中 ...
- MindSpore手写数字识别初体验,深度学习也没那么神秘嘛
摘要:想了解深度学习却又无从下手,不如从手写数字识别模型训练开始吧! 深度学习作为机器学习分支之一,应用日益广泛.语音识别.自动机器翻译.即时视觉翻译.刷脸支付.人脸考勤--不知不觉,深度学习已经渗入 ...
- 在同一个硬盘上安装多个 Linux 发行版及 Fedora 21 、Fedora 22 初体验
在同一个硬盘上安装多个 Linux 发行版 以前对多个 Linux 发行版的折腾主要是在虚拟机上完成.我的桌面电脑性能比较强大,玩玩虚拟机没啥问题,但是笔记本电脑就不行了.要在我的笔记本电脑上折腾多个 ...
- Microsoft IoT Starter Kit 开发初体验
1. 引子 今年6月底,在上海举办的中国国际物联网大会上,微软中国面向中国物联网社区推出了Microsoft IoT Starter Kit ,并且免费开放1000套的申请.申请地址为:http:// ...
- Java8初体验(一)lambda表达式语法
感谢同事[天锦]的投稿.投稿请联系 tengfei@ifeve.com 本文主要记录自己学习Java8的历程,方便大家一起探讨和自己的备忘.因为本人也是刚刚开始学习Java8,所以文中肯定有错误和理解 ...
- node.js 初体验
node.js 初体验 2011-10-31 22:56 by 聂微东, 174545 阅读, 118 评论, 收藏, 编辑 PS: ~ 此篇文章的进阶内容在为<Nodejs初阶之express ...
- Question2Answer初体验
Question2Answer初体验 高质量的问答社区十分有价值,很多无法解决的问题能通过问答社区找到解决办法,而对于站长来说,垂直的问答社区也很有潜力.最近盯上问答这一块,发现和我的一些思路很符 ...
随机推荐
- Oracle instant client免安装Oracle客户端配置
不想安装几个G的完整版client,可以直接通过安装包安装的时候选择instant client,如果没有安装包,也可以直接去官网下载一个即时客户端,64位的windows包大小只有78MB左右 传送 ...
- [LC]141题 Intersection of Two Linked Lists (相交链表)(链表)
①中文题目 编写一个程序,找到两个单链表相交的起始节点. 如下面的两个链表: 在节点 c1 开始相交. 注意: 如果两个链表没有交点,返回 null.在返回结果后,两个链表仍须保持原有的结构.可假定整 ...
- git Lab ssh方式拉取代码失败
gitLab在linux上已经安装好了, 在配置项目的时候报如下异常 使用http方式没问题, 但是用ssh方式设置repository URL 提示资源库不存在. returned status c ...
- 使用POI导出EXCEL工具类并解决导出数据量大的问题
POI导出工具类 工作中常常会遇到一些图表需要导出的功能,在这里自己写了一个工具类方便以后使用(使用POI实现). 项目依赖 <dependency> <groupId>org ...
- Linux系统时间\硬件时间(date、tzselect、clock、hwclock、ntpdate)
1.系统时间和硬件时间 在Linux中有硬件时钟与系统时钟两种时钟.硬件时钟是指主机板上的时钟设备,也就是通常可在BIOS画面设定的时钟.系统时钟则是指kernel中的时钟.所有Linux相关指令与函 ...
- CCF-画字符-详细的注释
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.i ...
- 一篇很好的学习查看Java源代码的文章
目录: 一. ArrayList概述 二. ArrayList的实现 1) 私有属性 2) 构造方法 3) 元素存储 4) 元素读取 5) 元素删除 6) 调整数组容量 ...
- 2019-11-22:xss绕过笔记
xss变形 大小写混合,sCRipt重复写,scrscriptipt通过某些标签来src属性,构造pyload,src找不到数据源的时候内部会出错,此时使用onerror触发,或iframe标签,&l ...
- 《VueRouter爬坑第三篇》-嵌套路由
VueRouter系列的文章示例编写时,项目是使用vue-cli脚手架搭建. 项目搭建的步骤和项目目录专门写了一篇文章:点击这里进行传送 后续VueRouter系列的文章的示例编写均基于该项目环境. ...
- 【Luogu P2563】【集训Day 4 动态规划】质数和分解
题目链接:Luogu P2563 质数和分解(prime) [问题描述] 任何大于 1 的自然数 N,都可以写成若干个大于等于2且小于等于 N 的质数之和表达式(包括只有一个数构成的和表达式的情况), ...