localhost
GET
Web 服务器使用请求的路径和方法来查找正确的资源,这被称为**“路由”**。
我们可以使用HTTP 动词方法、路径以及匹配时执行的函数来定义路由。
import { Elysia } from 'elysia'
new Elysia()
.get('/', 'hello')
.get('/hi', 'hi')
.listen(3000)我们可以通过访问 http://localhost:3000 来访问 Web 服务器。
默认情况下,Web 浏览器在访问页面时会发送 GET 方法。
GET
TIP
使用上面的交互式浏览器,将鼠标悬停在蓝色高亮区域,可以看到每个路径之间的不同结果。
Elysia 中的路径可以分为 3 种类型:
您可以将所有路径类型结合使用,以组合 Web 服务器的行为。
import { Elysia } from 'elysia'
new Elysia()
.get('/id/1', 'static path')
.get('/id/:id', 'dynamic path')
.get('/id/*', 'wildcard path')
.listen(3000)GET
静态路径是用于在服务器上定位资源的硬编码字符串。
import { Elysia } from 'elysia'
new Elysia()
.get('/hello', 'hello')
.get('/hi', 'hi')
.listen(3000)动态路径匹配某些部分并捕获值以提取额外信息。
要定义动态路径,我们可以使用冒号 : 后跟一个名称。
import { Elysia } from 'elysia'
new Elysia()
.get('/id/:id', ({ params: { id } }) => id)
.listen(3000)这里,创建了一个动态路径 /id/:id。这告诉 Elysia 捕获 :id 段的值,例如 /id/1、/id/123、/id/anything。
GET
当请求时,服务器应返回以下响应:
| 路径 | 响应 |
|---|---|
| /id/1 | 1 |
| /id/123 | 123 |
| /id/anything | anything |
| /id/anything?name=salt | anything |
| /id | Not Found |
| /id/anything/rest | Not Found |
动态路径非常适合包含像 ID 这样的内容,这些内容可以后续使用。
我们将命名变量路径称为路径参数或简称params。
您可以拥有任意数量的路径参数,这些参数将存储到一个 params 对象中。
import { Elysia } from 'elysia'
new Elysia()
.get('/id/:id', ({ params: { id } }) => id)
.get('/id/:id/:name', ({ params: { id, name } }) => id + ' ' + name)
.listen(3000)GET
服务器将响应如下:
| 路径 | 响应 |
|---|---|
| /id/1 | 1 |
| /id/123 | 123 |
| /id/anything | anything |
| /id/anything?name=salt | anything |
| /id | Not Found |
| /id/anything/rest | anything rest |
有时我们可能希望静态路径和动态路径解析到相同的处理程序。
我们可以通过在参数名称后添加问号 ? 来使路径参数成为可选的。
import { Elysia } from 'elysia'
new Elysia()
.get('/id/:id?', ({ params: { id } }) => `id ${id}`)
.listen(3000)GET
动态路径允许捕获单个段,而通配符允许捕获路径的其余部分。
要定义通配符,我们可以使用星号 *。
import { Elysia } from 'elysia'
new Elysia()
.get('/id/*', ({ params }) => params['*'])
.listen(3000)GET
Elysia 的路径优先级如下:
如果路径被解析为静态的,而动态路径存在,Elysia 将解析静态路径而不是动态路径。
import { Elysia } from 'elysia'
new Elysia()
.get('/id/1', 'static path')
.get('/id/:id', 'dynamic path')
.get('/id/*', 'wildcard path')
.listen(3000)GET
HTTP 定义了一组请求方法,以指示对给定资源执行的所需操作。
有几种 HTTP 动词,但最常见的有:
使用 GET 的请求应仅检索数据。
向指定资源提交负载,通常导致状态更改或副作用。
使用请求的负载替换目标资源的所有当前表示。
对资源应用部分修改。
删除指定的资源。
为了处理不同的动词,Elysia 默认内置了几个 HTTP 动词的 API,类似于 Elysia.get。
import { Elysia } from 'elysia'
new Elysia()
.get('/', 'hello')
.post('/hi', 'hi')
.listen(3000)GET
Elysia HTTP 方法接受以下参数:
您可以在 HTTP Request Methods 上阅读更多关于 HTTP 方法的信息。
我们可以使用 Elysia.route 来接受自定义 HTTP 方法。
import { Elysia } from 'elysia'
const app = new Elysia()
.get('/get', 'hello')
.post('/post', 'hi')
.route('M-SEARCH', '/m-search', 'connect')
.listen(3000)GET
Elysia.route 接受以下内容:
Elysia 提供了 Elysia.all,用于处理指定路径的任何 HTTP 方法,使用与 Elysia.get 和 Elysia.post 相同的 API。
import { Elysia } from 'elysia'
new Elysia()
.all('/', 'hi')
.listen(3000)GET
匹配路径的任何 HTTP 方法将按以下方式处理:
| 路径 | 方法 | 结果 |
|---|---|---|
| / | GET | hi |
| / | POST | hi |
| / | DELETE | hi |
大多数开发者使用像 Postman、Insomnia 或 Hoppscotch 这样的 REST 客户端来测试他们的 API。
然而,Elysia 可以使用 Elysia.handle 进行程序化测试。
import { Elysia } from 'elysia'
const app = new Elysia()
.get('/', 'hello')
.post('/hi', 'hi')
.listen(3000)
app.handle(new Request('http://localhost/')).then(console.log)Elysia.handle 是一个函数,用于处理发送到服务器的实际请求。
TIP
不同于单元测试的模拟,您可以期望它像发送到服务器的实际请求一样行为。
但也适用于模拟或创建单元测试。
在创建 Web 服务器时,您通常会有多个共享相同前缀的路由:
import { Elysia } from 'elysia'
new Elysia()
.post('/user/sign-in', 'Sign in')
.post('/user/sign-up', 'Sign up')
.post('/user/profile', 'Profile')
.listen(3000)POST
这可以通过 Elysia.group 来改进,允许我们通过将它们分组在一起,同时为多个路由应用前缀:
import { Elysia } from 'elysia'
new Elysia()
.group('/user', (app) =>
app
.post('/sign-in', 'Sign in')
.post('/sign-up', 'Sign up')
.post('/profile', 'Profile')
)
.listen(3000)POST
此代码的行为与我们的第一个示例相同,并应结构化为以下内容:
| 路径 | 结果 |
|---|---|
| /user/sign-in | Sign in |
| /user/sign-up | Sign up |
| /user/profile | Profile |
.group() 还可以接受一个可选的守卫参数,以减少使用组和守卫一起时的样板代码:
import { Elysia, t } from 'elysia'
new Elysia()
.group(
'/user',
{
body: t.Literal('Rikuhachima Aru')
},
(app) => app
.post('/sign-in', 'Sign in')
.post('/sign-up', 'Sign up')
.post('/profile', 'Profile')
)
.listen(3000)您可以在 scope 中找到更多关于分组守卫的信息。
我们可以通过向构造函数提供前缀来将组分离为单独的插件实例,以减少嵌套。
import { Elysia } from 'elysia'
const users = new Elysia({ prefix: '/user' })
.post('/sign-in', 'Sign in')
.post('/sign-up', 'Sign up')
.post('/profile', 'Profile')
new Elysia()
.use(users)
.get('/', 'hello world')
.listen(3000)GET