Remix 是一个全栈结构,能写 api 接口的能肯定是具有的,而且 Remix 尽管界说为全栈结构,此文章首要探究怎么接口。

本文内容

  • Remix 中 api 的书写办法
  • Remix 中 RESTful api 的属性办法
  • 类 MVC 分层接口怎么写 Remix
  • 处理上传示例

接口种类

  • 一般 get/post api:即可满足根本
  • RESTful API:有规范, 需求协同的
  • graphql:可操控需求的字段的,杰出的跨端

其间假如是一些小项目,没有必要规则化的项目,运用 get/post 处理就已经足够了,假如项目有了许多的人要保护,并且有了必定的规模,为了方便办理,可以运用 RESTful API 的办法处理。graphql API 手动才能最强。

RESTful API 特色

  • 创建:POST /api/resources
  • 读取:GET /api/resources/:id
  • 更新:PUT /api/resources/:id
  • 删去:DELETE /api/resources/:id

其间,:id 表示资源的仅有标识符。

Remix 中怎么处理 api 特色

  • loader 处理 get 恳求
  • action 处理非 get 恳求

Loader 函数处理 Get 恳求

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,
  });
};

增加操控层和服务层

为了代码更加好保护,有结构的代码时必要的,代码分层占据重要方位。

假如运用mongoose等会界说模型层,界说操作数据的模型,然后运用操控层来操作模型层。构成一个简略类 MVC 分层结构。当然 Remix 是一个根据 React + Node.js 全栈结构,运用模型层+服务层:

运用 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界说服务层,提供给 Remix loader 和 action 操作数据运用

// 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 函数中经过 services 层来获取数据,然后运用 json 函数回来数据。

运用 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 函数运用表单办法进行处理。

小结

本文首要关注点是与 Node.js 其他的结构有什么不同。loader 处理 get 办法,action 处理非 get 恳求。从一般的恳求处理到处理分层的进程,写好一个 api 的学习变化进程。