{"id":325,"date":"2026-04-19T05:08:38","date_gmt":"2026-04-19T05:08:38","guid":{"rendered":"https:\/\/hyc.eshachem.com\/program\/?p=325"},"modified":"2026-04-19T05:09:54","modified_gmt":"2026-04-19T05:09:54","slug":"%e5%9c%a8rsc%e6%9e%b6%e6%a7%8b%e4%b8%8b%e5%af%a6%e7%8f%benext-js-server-actions%ef%bc%8c%e5%ae%8c%e6%88%90%e8%a8%bb%e5%86%8a%e7%99%bb%e5%85%a5%e5%8a%9f%e8%83%bd%e5%8f%aa%e8%a6%8110%e5%88%86%e9%90%98","status":"publish","type":"post","link":"https:\/\/hyc.eshachem.com\/program\/%e5%9c%a8rsc%e6%9e%b6%e6%a7%8b%e4%b8%8b%e5%af%a6%e7%8f%benext-js-server-actions%ef%bc%8c%e5%ae%8c%e6%88%90%e8%a8%bb%e5%86%8a%e7%99%bb%e5%85%a5%e5%8a%9f%e8%83%bd%e5%8f%aa%e8%a6%8110%e5%88%86%e9%90%98\/","title":{"rendered":"\u5728RSC\u67b6\u69cb\u4e0b\u5be6\u73feNext.js Server Actions\uff0c\u5b8c\u6210\u8a3b\u518a\u767b\u5165\u529f\u80fd\u53ea\u898110\u5206\u9418!!"},"content":{"rendered":"\n<p>\u539f\u7db2\u5740:<a href=\"https:\/\/eminent-glider-8c3.notion.site\/Next-js-Server-Actions-10-3239def5443d804bbec8d6ef9c5b0983?source=copy_link\">Notion<\/a><\/p>\n\n\n\n<p>RSC \u662fNext.js\u8fd1\u5e74(2026)\u6700\u63a8\u85a6\u7684\u67b6\u69cb\uff0c\u4e0d\u50c5\u5927\u5e45\u63d0\u5347\u4e86DX (Developer experience)\uff0c\u5728Browser render\u7684\u6548\u80fd\u4e5f\u5927\u5e45\u63d0\u5347\u4e86\uff0c\u751a\u81f3Next.js Server Actions\u80fd\u66f4\u52a0\u96b1\u79c1\u7684\u5b8c\u6210API\u7684\u9023\u63a5\u3002<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">\u5c08\u6848\u67b6\u69cb<\/h1>\n\n\n\n<ul class=\"wp-block-list\">\n<li>RSC ( React Server Components )<\/li>\n\n\n\n<li>shadcn-ui (Tailwind CSS) <a href=\"https:\/\/www.notion.so\/Tailwind-CSS-31d9def5443d80a99937e79d0e470836?pvs=21\">Tailwind CSS<\/a><\/li>\n\n\n\n<li>MongoDB <a href=\"https:\/\/www.notion.so\/Use-MERN-stack-to-dev-Full-Stack-web-2d59def5443d80a194a5e8d6bf6d740a?pvs=21\">Use <em>\u201cMERN\u201d<\/em> stack to dev. Full-Stack web<\/a><\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>src\/\n\u2514\u2500\u2500 app\/\n    \u2514\u2500\u2500 auth\/\n        \u251c\u2500\u2500 page.tsx       (Client Component: \u8ca0\u8cac\u4e92\u52d5\u4e8b\u4ef6)\n        \u2514\u2500\u2500 actions.ts     (Server Actions: \u8ca0\u8cac POST\/DELETE\/UPDATE)<\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">MongoDB<\/h1>\n\n\n\n<p>\u8cc7\u6599\u5eab\u5982\u4e0b:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Cluster0\/\n\u2514\u2500\u2500 DB\/ (DataBase)\n    \u2514\u2500\u2500 auth (Collection)<\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">Page.tsx<\/h1>\n\n\n\n<p>\u9019\u88e1\u662f\u9801\u9762\u5c0e\u51fa\u7684\u5730\u65b9\uff0c\u56e0\u70ba\u6703\u6709\u4e92\u52d5\u4e8b\u4ef6\u6240\u4ee5\u662f<code>\u201duse Client\u201d<\/code><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>CommonFields : \u7a0b\u5f0f\u78bc\u91cd\u7528\u6027 DRY (Don&#8217;t Repeat Yourself)<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>\"use client\"\n\nimport React, { useActionState } from \"react\"\nimport Link from \"next\/link\"\nimport { Button } from \"@\/components\/ui\/button\"\nimport { Card, CardContent, CardHeader, CardTitle, CardDescription } from \"@\/components\/ui\/card\"\nimport { Input } from \"@\/components\/ui\/input\"\nimport { Label } from \"@\/components\/ui\/label\"\nimport { Tabs, TabsList, TabsTrigger, TabsContent } from \"@\/components\/ui\/tabs\"\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"@\/components\/ui\/select\"\nimport { handleAuth } from \".\/actions\"\n\nexport default function AuthPage() {\n  const &#91;state, formAction, isPending] = useActionState(handleAuth, null)\n  const CommonFields = () =&gt; ( \/\/ \u7b26\u5408DRY\u539f\u5247\n    &lt;&gt;\n      &lt;div className=\"space-y-2\"&gt;\n        &lt;Label&gt;Email&lt;\/Label&gt;\n        &lt;Input name=\"email\" type=\"email\" placeholder=\"you@example.com\" required \/&gt;\n      &lt;\/div&gt;\n      &lt;div className=\"space-y-2\"&gt;\n        &lt;Label&gt;Password&lt;\/Label&gt;\n        &lt;Input name=\"password\" type=\"password\" required \/&gt;\n      &lt;\/div&gt;\n    &lt;\/&gt;\n  )\n  return (\n    &lt;div className=\"flex min-h-screen items-center justify-center bg-background px-4\"&gt;\n      &lt;div className=\"w-full max-w-md\"&gt;\n        &lt;Card className=\"bg-card\/90 backdrop-blur-sm shadow-sm border-border\"&gt;\n          &lt;CardHeader className=\"space-y-2 text-center\"&gt;\n            &lt;CardTitle className=\"text-xl font-semibold text-foreground\"&gt;Welcome&lt;\/CardTitle&gt;\n            &lt;CardDescription className=\"text-sm text-muted-foreground\"&gt;\u767b\u5165\u6216\u8a3b\u518a!&lt;\/CardDescription&gt;\n          &lt;\/CardHeader&gt;\n\n          &lt;CardContent&gt;\n            {state?.error &amp;&amp; &lt;div className=\"p-2 mb-4 text-sm text-red-500 bg-red-50 rounded border border-red-200\"&gt;{state.error}&lt;\/div&gt;}\n            {state?.success &amp;&amp; &lt;div className=\"p-2 mb-4 text-sm text-green-500 bg-green-50 rounded border border-green-200\"&gt;{state.success}&lt;\/div&gt;}\n\n            &lt;Tabs defaultValue=\"login\" className=\"w-full\"&gt;\n              &lt;TabsList className=\"grid w-full grid-cols-2 bg-muted\/60\"&gt;\n                &lt;TabsTrigger value=\"login\"&gt;\u767b\u5165&lt;\/TabsTrigger&gt;\n                &lt;TabsTrigger value=\"register\"&gt;\u8a3b\u518a&lt;\/TabsTrigger&gt;\n              &lt;\/TabsList&gt;\n\n              {\/* \u767b\u5165\u8868\u55ae *\/}\n              &lt;TabsContent value=\"login\"&gt;\n                &lt;form action={formAction} className=\"mt-6 space-y-4\"&gt;\n                  &lt;input type=\"hidden\" name=\"auth-type\" value=\"login\" \/&gt;\n                  &lt;CommonFields\/&gt;\n                  &lt;Button className=\"w-full mt-2\" disabled={isPending}&gt;{isPending ? \"\u8655\u7406\u4e2d...\" : \"\u767b\u5165\"}&lt;\/Button&gt;\n                &lt;\/form&gt;\n              &lt;\/TabsContent&gt;\n\n              {\/* \u8a3b\u518a\u8868\u55ae *\/}\n              &lt;TabsContent value=\"register\"&gt;\n                &lt;form action={formAction} className=\"mt-6 space-y-4\"&gt;\n                  &lt;input type=\"hidden\" name=\"auth-type\" value=\"register\" \/&gt;\n                  &lt;div className=\"space-y-2\"&gt;\n                    &lt;Label htmlFor=\"name\"&gt;Name&lt;\/Label&gt;\n                    &lt;Input id=\"name\" name=\"name\" placeholder=\"Jane Doe\" required \/&gt;\n                  &lt;\/div&gt;\n                  &lt;div className=\"space-y-2\"&gt;\n                    &lt;Label htmlFor=\"role\"&gt;Role (\u8eab\u5206)&lt;\/Label&gt;\n                    &lt;Select name=\"role\" defaultValue=\"DEV\"&gt;\n                      &lt;SelectTrigger&gt;\n                        &lt;SelectValue placeholder=\"\u9078\u64c7\u4f60\u7684\u89d2\u8272\" \/&gt;\n                      &lt;\/SelectTrigger&gt;\n                      &lt;SelectContent&gt;\n                        &lt;SelectItem value=\"PO\"&gt;Product Owner (PO)&lt;\/SelectItem&gt;\n                        &lt;SelectItem value=\"DEV\"&gt;Developer (DEV)&lt;\/SelectItem&gt;\n                        &lt;SelectItem value=\"TL\"&gt;Team Lead (TL)&lt;\/SelectItem&gt;\n                      &lt;\/SelectContent&gt;\n                    &lt;\/Select&gt;\n                  &lt;\/div&gt;\n                  &lt;CommonFields\/&gt;\n                  &lt;Button className=\"w-full mt-2\" disabled={isPending}&gt;{isPending ? \"\u5efa\u7acb\u5e33\u865f\u4e2d...\" : \"\u5efa\u7acb\u5e33\u865f\"}&lt;\/Button&gt;\n                &lt;\/form&gt;\n              &lt;\/TabsContent&gt;\n            &lt;\/Tabs&gt;\n            &lt;p className=\"mt-6 text-center text-xs text-muted-foreground\"&gt;\n              @2026 Hy.Chen\n            &lt;\/p&gt;\n          &lt;\/CardContent&gt;\n        &lt;\/Card&gt;\n      &lt;\/div&gt;\n    &lt;\/div&gt;\n  )\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">useActionState<\/h2>\n\n\n\n<p>\u662f <strong>React 19\u63a8\u51fa\u7684\u8868\u55ae\u7ba1\u7406hook<\/strong><\/p>\n\n\n\n<p><a href=\"https:\/\/zh-hans.react.dev\/reference\/react\/useActionState\">https:\/\/zh-hans.react.dev\/reference\/react\/useActionState<\/a><\/p>\n\n\n\n<p><code>const [state, formAction, isPending] = useActionState(handleAuth, null)<\/code><\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th><strong>\u8b8a\u6578\u540d\u7a31<\/strong><\/th><th><strong>\u540d\u7a31<\/strong><\/th><th><strong>\u505a\u4ec0\u9ebc\u7528\u7684\uff1f<\/strong><\/th><\/tr><\/thead><tbody><tr><td><strong><code>state<\/code><\/strong><\/td><td><strong>Action \u72c0\u614b<\/strong><\/td><td>\u9019\u662f<strong>\u5f8c\u7aef\u56de\u50b3\u7684\u7d50\u679c<\/strong>\uff08\u4f8b\u5982\uff1a<code>{ error: \"\u5bc6\u78bc\u932f\u8aa4\" }<\/code>\uff09\u3002\u5b83\u8b93\u4f60\u80fd\u5728\u524d\u7aef\u756b\u9762\u986f\u793a\u300c\u8a3b\u518a\u6210\u529f\u300d\u6216\u300c\u5831\u932f\u300d\u3002<\/td><\/tr><tr><td><strong><code>formAction<\/code><\/strong><\/td><td><strong>\u8868\u55ae\u52d5\u4f5c<\/strong><\/td><td>\u4f60\u8981\u628a\u5b83\u653e\u5728 <code>&lt;form action={formAction}&gt;<\/code>\u3002\u7576\u7528\u6236\u9ede\u64ca\u6309\u9215\uff0c\u5b83\u6703\u81ea\u52d5\u628a\u6574\u4efd\u8868\u55ae\u8cc7\u6599\u4e1f\u7d66\u5f8c\u7aef\u3002<\/td><\/tr><tr><td><strong><code>isPending<\/code><\/strong><\/td><td><strong>\u8655\u7406\u72c0\u614b<\/strong><\/td><td>\u4e00\u500b <strong>\u5e03\u6797\u503c (true\/false)<\/strong>\u3002\u7576\u8cc7\u6599\u6b63\u5728\u50b3\u8f38\u6642\uff0c\u5b83\u662f <code>true<\/code>\u3002\u9019\u8b93\u4f60\u80fd\u5728\u6309\u9215\u4e0a\u986f\u793a\u300c\u8f49\u5708\u5708\u300d\u6216\u8b8a\u66f4\u6587\u5b57\u3002<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>\u53d6\u4ee3\u4e86\u50b3\u7d71\u5beb\u6cd5:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const &#91;loading, setLoading] = useState(false);\nconst &#91;error, setError] = useState(null);\nconst &#91;data, setData] = useState(null);<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">shadcn\/ui<\/h2>\n\n\n\n<p>\u8907\u96dc\u4e92\u52d5\uff1aTabs &amp; Select<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Tabs (\u5207\u63db\u5206\u9801)<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>TabsList<\/strong>: \u5206\u9801\u7684\u6309\u9215\u5bb9\u5668\u3002<\/li>\n\n\n\n<li><strong>TabsTrigger<\/strong>: \u500b\u5225\u7684\u5207\u63db\u6309\u9215\u3002<\/li>\n\n\n\n<li><strong>TabsContent<\/strong>: \u5c0d\u61c9\u5167\u5bb9\u3002<\/li>\n\n\n\n<li><strong>\u539f\u7406\uff1a<\/strong> \u5b83\u8655\u7406\u4e86\u9375\u76e4\u5c0e\u89bd\uff08\u4e0a\u4e0b\u5de6\u53f3\u9375\u5207\u63db\u5206\u9801\uff09\u8207 ARIA \u89d2\u8272\u5206\u914d\uff0c\u8b93\u4f60\u7684\u767b\u5165\/\u8a3b\u518a\u5207\u63db\u7b26\u5408 Web \u6a19\u6e96\u3002<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Select (\u4e0b\u62c9\u9078\u55ae)<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>SelectTrigger &amp; SelectValue<\/strong>: \u8ca0\u8cac\u986f\u793a\u76ee\u524d\u7684\u9078\u64c7\u3002<\/li>\n\n\n\n<li><strong>SelectContent &amp; SelectItem<\/strong>: \u8ca0\u8cac\u5f48\u51fa\u7684\u9078\u55ae\u6e05\u55ae\u3002<\/li>\n\n\n\n<li><strong>\u512a\u52e2\uff1a<\/strong> \u89e3\u6c7a\u4e86\u539f\u751f <code>&lt;select><\/code> \u5728\u4e0d\u540c\u700f\u89bd\u5668\uff08Chrome vs Safari\uff09\u6a23\u5f0f\u96e3\u4ee5\u7d71\u4e00\u7684\u75db\u9ede\uff0c\u540c\u6642\u652f\u63f4\u6f02\u4eae\u7684\u52d5\u756b\u6548\u679c\u3002<\/li>\n<\/ul>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>shadcn\/ui \u7684\u6838\u5fc3\u50f9\u503c\u5728\u65bc\u5b83\u9075\u5faa\u4e86 <strong>Composition Pattern (\u7d44\u5408\u6a21\u5f0f)<\/strong>\uff0c\u9019\u8b93\u6211\u5011\u7684 <code>AuthPage<\/code> \u5373\u4f7f\u908f\u8f2f\u8907\u96dc\uff0c\u7a0b\u5f0f\u78bc\u7d50\u69cb\u4f9d\u7136\u6e05\u6670\u53ef\u8b80\uff0c\u4e14\u5177\u5099\u5b8c\u6574\u7684\u7121\u969c\u7919\u652f\u6301\u3002<\/p>\n<\/blockquote>\n\n\n\n<h1 class=\"wp-block-heading\">actions.ts<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">\u4e8b\u524d\u4f5c\u696d<\/h2>\n\n\n\n<p><code>.env.local<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># .env.local\nMONGODB_URI=mongodb+srv:\/\/&lt;username&gt;:&lt;password&gt;@cluster.mongodb.net\/Agile-ESS?retryWrites=true&amp;w=majority<\/code><\/pre>\n\n\n\n<p><code>bcryptjs<\/code> :\u4e00\u500b\u5c08\u9580\u70ba\u5bc6\u78bc\u96dc\u6e4aHashing\u8a2d\u8a08\u7684\u51fd\u5f0f\u5eab<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm install bcrypt\nnpm install --save-dev @types\/bcrypt<\/code><\/pre>\n\n\n\n<p><code>mongodb<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm install mongodb<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>\"use server\"\n\nimport { MongoClient } from \"mongodb\"\nimport bcrypt from \"bcrypt\"\nimport { redirect } from \"next\/navigation\"\n\nconst client = new MongoClient(process.env.MONGODB_URI!)\n\nexport async function handleAuth(prevState: any, formData: FormData) {\n  const type = formData.get(\"auth-type\") \/\/ \u5224\u65b7\u662f login \u9084\u662f register\n  const email = formData.get(\"email\") as string\n  const password = formData.get(\"password\") as string\n\n  await client.connect()\n  const db = client.db(\"ESS-db\")\n  const collection = db.collection(\"user\")\n\n  if (type === \"register\") {\n    const name = formData.get(\"name\") as string\n    const role = formData.get(\"role\") as string\n\n    \/\/ \u6aa2\u67e5\u91cd\u8907\n    const existing = await collection.findOne({ email })\n    if (existing) return { error: \"\u8a72 Email \u5df2\u88ab\u8a3b\u518a\" }\n\n    \/\/ \u52a0\u5bc6\u4e26\u5132\u5b58\n    const hashedPassword = await bcrypt.hash(password, 10)\n    await collection.insertOne({\n      name,\n      email,\n      password: hashedPassword,\n      role,\n      createdAt: new Date()\n    })\n\n    return { success: \"\u8a3b\u518a\u6210\u529f\uff01\u8acb\u5207\u63db\u81f3\u767b\u5165\u5206\u9801\" }\n  }\n\n  if (type === \"login\") {\n    const user = await collection.findOne({ email })\n    if (!user) return { error: \"\u7528\u6236\u4e0d\u5b58\u5728\" }\n\n    const isMatch = await bcrypt.compare(password, user.password)\n    if (!isMatch) return { error: \"\u5bc6\u78bc\u932f\u8aa4\" }\n\n    \/\/ \u9019\u88e1\u901a\u5e38\u6703\u8a2d\u5b9a Cookie\/Session\uff0c\u76ee\u524d\u5148\u6a21\u64ec\u6210\u529f\u5c0e\u5411\n    redirect(\"\/dashboard\")\n  }\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Props<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><code>prevState<\/code><\/strong>: \u56e0\u70ba\u6211\u5011\u524d\u7aef\u4f7f\u7528\u4e86 <code>useActionState<\/code>\uff0c\u6240\u4ee5\u7b2c\u4e00\u500b\u53c3\u6578\u5fc5\u9808\u662f\u300c\u4e0a\u4e00\u6b21\u7684\u72c0\u614b\u300d\u3002\u96d6\u7136\u9019\u88e1\u6c92\u7528\u5230\uff0c\u4f46\u4f4d\u7f6e\u5fc5\u9808\u7559\u8457\u3002<\/li>\n\n\n\n<li><strong><code>formData.get(...)<\/code><\/strong>: \u9019\u662f\u539f\u751f Web API\u3002Server Actions \u6700\u512a\u96c5\u7684\u5730\u65b9\u5728\u65bc\u5b83\u76f4\u63a5\u8655\u7406 <code>FormData<\/code> \u7269\u4ef6\uff0c\u4f60\u4e0d\u9700\u8981\u50cf\u4ee5\u524d\u4e00\u6a23\u5beb <code>req.body.email<\/code>\u3002<\/li>\n\n\n\n<li><strong><code>as string<\/code><\/strong>: \u5f37\u5236\u8f49\u578b\uff0c\u56e0\u70ba <code>get<\/code> \u62ff\u5230\u7684\u53ef\u80fd\u662f\u6a94\u6848\u6216\u5b57\u4e32\uff0c\u6211\u5011\u660e\u78ba\u544a\u77e5\u9019\u662f\u6587\u5b57\u3002<\/li>\n\n\n\n<li><strong>\u9023\u7dda\u4e09\u90e8\u66f2<\/strong>: <code>connect()<\/code> (\u9023\u63a5) -> <code>db()<\/code> (\u9078\u64c7\u8cc7\u6599\u5eab) -> <code>collection()<\/code> (\u9078\u64c7\u8cc7\u6599\u8868)\u3002<\/li>\n<\/ul>\n\n\n\n<p>\u7528Server Actions\u7684\u5beb\u6cd5\u5be6\u73fe\u4e86\u6700&#8221;\u6574\u6f54\u201d\u7684\u5beb\u6cd5\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u96f6 API Route<\/strong>: \u4f60\u4e0d\u9700\u8981\u5beb <code>\/api\/login<\/code>\u3002<\/li>\n\n\n\n<li><strong>\u578b\u5225\u5b89\u5168<\/strong>: \u8cc7\u6599\u5f9e\u8868\u55ae\u5230\u8cc7\u6599\u5eab\u7684\u6d41\u5411\u6e05\u6670\u53ef\u898b\u3002<\/li>\n\n\n\n<li><strong>\u5b89\u5168\u6027<\/strong>: \u6240\u6709\u654f\u611f\u64cd\u4f5c\uff08\u52a0\u5bc6\u3001DB \u9023\u7dda\uff09\u90fd\u96b1\u85cf\u5728 <code>\"use server\"<\/code> \u7246\u5f8c\u3002<\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>\u539f\u7db2\u5740:Notion RSC \u662fNext.js\u8fd1\u5e74(2026)\u6700\u63a8\u85a6\u7684\u67b6\u69cb\uff0c\u4e0d\u50c5\u5927\u5e45\u63d0\u5347\u4e86DX (Developer experience)\uff0c\u5728Browser render\u7684\u6548\u80fd\u4e5f\u5927\u5e45\u63d0\u5347\u4e86\uff0c\u751a\u81f3Next.js Server Actions\u80fd\u66f4\u52a0\u96b1\u79c1\u7684\u5b8c\u6210API\u7684\u9023\u63a5\u3002 \u5c08\u6848\u67b6\u69cb MongoDB [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[15],"tags":[],"class_list":["post-325","post","type-post","status-publish","format-standard","hentry","category-front-end"],"_links":{"self":[{"href":"https:\/\/hyc.eshachem.com\/program\/wp-json\/wp\/v2\/posts\/325","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hyc.eshachem.com\/program\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hyc.eshachem.com\/program\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hyc.eshachem.com\/program\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/hyc.eshachem.com\/program\/wp-json\/wp\/v2\/comments?post=325"}],"version-history":[{"count":1,"href":"https:\/\/hyc.eshachem.com\/program\/wp-json\/wp\/v2\/posts\/325\/revisions"}],"predecessor-version":[{"id":326,"href":"https:\/\/hyc.eshachem.com\/program\/wp-json\/wp\/v2\/posts\/325\/revisions\/326"}],"wp:attachment":[{"href":"https:\/\/hyc.eshachem.com\/program\/wp-json\/wp\/v2\/media?parent=325"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hyc.eshachem.com\/program\/wp-json\/wp\/v2\/categories?post=325"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hyc.eshachem.com\/program\/wp-json\/wp\/v2\/tags?post=325"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}