一文學(xué)會(huì)使用Remix寫API接口
本文提要
Remix 是一個(gè)全??蚣埽軐?api 接口的能肯定是具備的,而且 Remix 雖然定義為全??蚣?,此文章主要探索如何接口。
- Remix 中 api 的書寫方式
- Remix 中 RESTful api 的屬性方式
- 類 MVC 分層接口如何寫 Remix
- 處理上傳示例
接口種類
- 普通 get/post api:即可滿足基本
- RESTful API:有規(guī)范, 需要協(xié)同的
- graphql:可控制需要的字段的,良好的跨端
其中如果是一些小項(xiàng)目,沒有必要規(guī)則化的項(xiàng)目,使用 get/post 處理就已經(jīng)足夠了,如果項(xiàng)目有了很多的人要維護(hù),并且有了一定的規(guī)模,為了方便管理,可以使用 RESTful API 的方式處理。graphql API 手動(dòng)能力最強(qiáng)。
RESTful API 特點(diǎn)
- 創(chuàng)建:POST /api/resources
- 讀?。篏ET /api/resources/:id
- 更新:PUT /api/resources/:id
- 刪除:DELETE /api/resources/:id
其中,:id 表示資源的唯一標(biāo)識(shí)符。
Remix 中如何處理 api 特點(diǎn)
- loader 處理 get 請(qǐng)求
- action 處理非 get 請(qǐng)求
Loader 函數(shù)處理 Get 請(qǐng)求
export const loader = () => {
return json({ get: 'loader get' })
}
action 處理非 GET 方法
import { json } from "@remix-run/node";
const handleNotGetRequest = function ({ request }) {
const method = request.method;
switch (method) {
case "POST":
return json({ code: 0, method: "POST", message: "添加成功" });
case "PUT":
return json({ ok: true, code: 1, method: "PUT", message: "修改成功" });
case "DELETE":
return json({ ok: true, code: 1, method: "PUT", message: "刪除成功" });
default:
break;
}
};
// 非 get
export const action = ({ request }) => {
return handleNotGetRequest({ request });
};
// get
export const loader = ({ request }) => {
return json({
a: 1,
});
};
添加控制層和服務(wù)層
為了代碼更加好維護(hù),有結(jié)構(gòu)的代碼時(shí)必要的,代碼分層占據(jù)重要位置。
如果使用 mongoose 等會(huì)定義模型層,定義操作數(shù)據(jù)的模型,然后使用控制層來操作模型層。構(gòu)成一個(gè)簡(jiǎn)單類 MVC 分層結(jié)構(gòu)。當(dāng)然 Remix 是一個(gè)基于 React + Node.js 全??蚣?,使用模型層+服務(wù)層:
使用 mongoose 定義模型層, category.model.ts
import mongoose from 'mongoose'
const CategorySchema = new mongoose.Schema({
name: String,
description: String,
createdAt: Date,
articleIds: [String]
})
export default mongoose.models.Category ||
mongoose.model('Category', CategorySchema)
使用 category.service.ts 定義服務(wù)層,提供給 Remix loader 和 action 操作數(shù)據(jù)使用
// model
import Category from '~/models/category.model'
export const delCategoryById = async (_id: string) => {
return await Category.remove({ _id })
}
export const findCategoryByName = async (name: string) => {
return await Category.findOne({ name })
}
export const updateCategoryById = async (_id: string, update: any) => {
return await Category.findByIdAndUpdate({ _id }, update)
}
export const findCategoryById = async (_id: string) => {
return await Category.findOne({ _id })
}
export const addCategoryByName = async (name: string) => {
const CategoryEntify = new Category({ name, createdAt: new Date() })
return await CategoryEntify.save()
}
暴露 loader 接口
// core
import { json } from '@remix-run/node'
// service
import * as categoryService from '~/services/category.service'
// remix loader
export async function loader() {
const list = await categoryService
.getCategoryList({}, '_id createdAt name articleIds', 0, 100000)
.then((list) => list)
return json({ code: 0, message: 'success', data: { list } }, 200)
}
在 loader 函數(shù)中通過 services 層來獲取數(shù)據(jù),然后使用 json 函數(shù)返回?cái)?shù)據(jù)。
使用 action 方法處理文件上傳接口
api.upload.files.tsx上傳文件到本地
import type { ActionArgs } from '@remix-run/node'
import {
json,
unstable_composeUploadHandlers as composeUploadHandlers,
unstable_createFileUploadHandler as createFileUploadHandler,
unstable_createMemoryUploadHandler as createMemoryUploadHandler,
unstable_parseMultipartFormData as parseMultipartFormData
} from '@remix-run/node'
// single file upload
export const action = async ({ request }: ActionArgs) => {
const uploadHandler = composeUploadHandlers(
createFileUploadHandler({
directory: 'public/uploads', // 指定上傳目錄
maxPartSize: 30000000, // 指定大小
file: (file) => {
return file.filename
}
}),
createMemoryUploadHandler()
)
const formData = await parseMultipartFormData(request, uploadHandler)
return json({ imgSrc: formData.get('file') }) // 返回文件名
}
上傳使用 post 方法,在 action 函數(shù)使用表單方式進(jìn)行處理。
小結(jié)
本文主要關(guān)注點(diǎn)是與 Node.js 其他的框架有什么不同。loader 處理 get 方法,action 處理非 get 請(qǐng)求。從普通的請(qǐng)求處理到處理分層的過程,寫好一個(gè) api 的學(xué)習(xí)變化過程。
更多關(guān)于Remix API接口的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
react組件中的constructor和super知識(shí)點(diǎn)整理
這篇文章主要介紹了react組件中的constructor和super知識(shí)點(diǎn)整理,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-08-08
詳解React Native頂|底部導(dǎo)航使用小技巧
本篇文章主要介紹了詳解React Native頂|底部導(dǎo)航使用小技巧 ,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-09-09
Objects are not valid as a Rea
這篇文章主要為大家介紹了Objects are not valid as a React child報(bào)錯(cuò)解決方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12
React Native全面屏狀態(tài)欄和底部導(dǎo)航欄適配教程詳細(xì)講解
最近在寫 React Native 項(xiàng)目,調(diào)試應(yīng)用時(shí)發(fā)現(xiàn)頂部狀態(tài)欄和底部全面屏手勢(shì)指示條區(qū)域不是透明的,看起來很難受。研究了一下這個(gè)問題,現(xiàn)在總結(jié)一下解決方案,這篇文章主要介紹了React Native全面屏狀態(tài)欄和底部導(dǎo)航欄適配教程2023-01-01
react 應(yīng)用多入口配置及實(shí)踐總結(jié)
這篇文章主要介紹了react 應(yīng)用多入口配置及實(shí)踐總結(jié),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-10-10

