# Strapi基本概念及架構(Strapi介紹-中篇) <!-- Put the link to this slide here so people can follow --> 來源: https://strapi.io/documentation/3.0.0-beta.x/concepts/concepts.html [前篇(快速入門)](https://hackmd.io/oXdEw-gBTSGheNsARMJYVg) [中篇(概念架構介紹)](https://hackmd.io/LqgfRVBXQf-OYFrvdiT7Hw) [後篇(部署及設定)](https://hackmd.io/-2zeYcrgR52aI-gssI-XFQ) :cat: 簡單介紹Strapi的概念與架構 --- ## 1. Strapi 檔案結構(僅介紹API, config檔案) ### API, config, ... - **(其他資料夾) - /api - **(你的API名稱,ex: restaurant) - config - controllers - models - services - /config - environments - ... --- ## 2. Strapi 概略運作流程 ```flow st=>start: Request請求 e=>end: Response最終回應! cond1=>inputoutput: ROUTE(分配) cond=>condition: have policy? (有無分配規則?) sub=>subroutine: Policy(執行規則) (e.g., isAnthenticated?...) op=>operation: Controller(控制器) op2=>operation: Service(執行服務) st(right)->cond1->cond cond(no)->op()->op2(right)->e cond(yes)->sub->op ``` :::info 以 restaurant 資料為例 ::: ### Request (此Request介紹為一般的客戶端請求,非原文檔中的Request) 來自客戶端的請求 發送請求給==Route==端處理 ```javascript= Url: http://localhost:1337/restaurants Method: GET //axios 取得所有restaurants的資料 axios({ url: http://localhost:1337/restaurants, method: 'GET', }) .then(res => { console.log(res.response.data); }) .catch(err => { console.log('An error occurred:', err.response); }); ``` ### Route(包含分配方法及policies) [原文連結](https://strapi.io/documentation/3.0.0-beta.x/guides/policies.html#how-to-create-a-policy) 取得請求後,依照各API的routes.json檔案去做請求的分配,分配給==controller==處理 - 檔案路徑- `./api/restaurant/config/routes.json` ```json= { "routes": [ { "method": "GET", "path": "/restaurants", "handler": "Restaurant.find", //controller的方法 "config": { "policies": [ //如沒有則不處理policy "global.isAuthenticated" ] } } ] } ``` ### Controller [原文連結](https://strapi.io/documentation/3.0.0-beta.x/guides/controllers.html) 從Route中的 **handler** 取得的方法來做任務執行(類似redux 的 action),將執行==services==中的方法 - 以下為strapi的原本方法的原始碼 - 檔案路徑(自訂方法會直接覆蓋原有方法)- `./api/restaurant/controllers/Restaurants.js` `find` ```javascript= module.exports = { /** * Retrieve records. * * @return {Array} */ //可自訂使用的service方法 find(ctx) { if (ctx.query._q) { //將執行product中的service的search方法 return strapi.services.restaurant.search(ctx.query); } return strapi.services.restaurant.find(ctx.query); //也可以不往service,直接丟出資料 //return 'Hi' }, }; ``` ### Service [原文連結](https://strapi.io/documentation/3.0.0-beta.x/guides/services.html) 取得來自controller的方法呼叫,執行對應的service方法 - 檔案路徑(自訂方法會直接覆蓋原有方法)- `./api/restaurant/services/Restaurants.js` `find` ```javascript= module.exports = { /** * Promise to fetch all records * * @return {Promise} */ find(params, populate) { return strapi.query(Restaurant).find(params, populate); }, }; ``` ### Response [原文連結(response原始資料)](https://strapi.io/documentation/3.0.0-beta.x/guides/responses.html#response) 取得service或是controller的資料 e.g., 取得find的資料(API取得的資料) `find` ```json= //API拿到的資料 [{"id":1,"restaurant":"Strapi Restaurant","description":"Strapi restaurant is a cosy restaurant delivering one of the very fastest and nicest dining experiences in the world, combining nods to tradition with fierce modernity, warmth with daring.","created_at":"2019-07-31T03:41:56.793Z","updated_at":"2019-07-31T03:44:09.395Z","categories":[{"id":1,"category":"Convenient","created_at":"2019-07-31T03:42:15.241Z","updated_at":"2019-07-31T07:17:32.389Z"},{"id":2,"category":"Time Saving","created_at":"2019-07-31T03:43:25.358Z","updated_at":"2019-07-31T03:43:25.364Z"}]}] ``` --- ## 3. Model 資料模型 [原文連結](https://strapi.io/documentation/3.0.0-beta.x/guides/models.html) 簡單來說,就是在[strapi快速入門](https://hackmd.io/oXdEw-gBTSGheNsARMJYVg?view)中,用==新增欄位==功能產生的資料模型 而我們可以直接使用指令或是修改檔案的方式,來直接新增或是修改欄位! :::info 在新建一個API之後,strapi會自動產生model檔 ::: 如果在該API資料夾中無model檔案,可以透過以下CLI指令新建一個 `strapi generate:model restaurant name:string` ### attributes 格式(type) 有以下格式可以使用 `string, text, integer, biginteger, float, decimal, password, date, time, datetime, timestamp, boolean, binary, uuid, enumeration, json, email` ### validations 驗證 有以下驗證可以使用 `required (boolean)`: 是否必須 `unique (boolean)`: 是否唯一 `index(boolean)`: 是否加上索引值(僅適用mongoDB) `max (integer)`: 最大值(整數) `min (integer)`: 最小值(整數) ### 以restaurant為例 路徑- `./api/restaurant/models/Restaurant.settings.json` ```json= { "connection": "default", "collectionName": "restaurants", "info": { "name": "restaurant", //api名稱 "description": "" //api描述 }, "options": { "increments": true, "timestamps": true, "comment": "" ... //選項解釋詳見原文 }, "attributes": { "restaurant": { //restaurant的欄位 "unique": true, //驗證: 唯一 "required": true, //驗證: 必須 "type": "string" //格式: 字串 }, "description": { "type": "text" //格式: 文字 }, "categories": { //此為多個restaurants對多個categories(多對多) "collection": "category", //關聯的欄位(多個的集合) "via": "restaurants" //關聯到自己的欄位(多個) } } } ``` ### relations 資料關係 [詳細範例以及controller相關使用方法請看這邊](https://strapi.io/documentation/3.0.0-beta.x/guides/models.html#relations) - One-way 單向 - One-to-one 一對一 - One-to-many 一對多 - Many-to-many 多對多 #### One-way 單向 資料之間只有單向的連結,例如`pet`的`owner`連結到某位`user`,而`user`不會有相應的`pet`關係 Example: Path — `./api/pet/models/Pet.settings.json` ```json= { "attributes": { "owner": { "model": "user" } } } ``` #### One-to-one 一對一 資料之間為一對一的連結關係,例如`user`會有一個`address`,且`address`也會有一個相應的`user`欄位 Example: Path - `./api/user/models/User.settings.json` ```json= { "attributes": { "address": { "model": "address", //連結address "via": "user" } } } ``` Path - `./api/address/models/Address.settings.json` ```json= { "attributes": { "user": { "model": "user" } } } ``` #### One-to-many 一對多(多對一) 資料之間為一對多(多對一)的連結關係,例如`user`會有很多個`articles`,且`article`也會有相應的`user(article)`欄位 Example: `user` Path - `./api/user/models/User.settings.json` ```json= { "attributes": { "articles": { "collection": "article", "via": "author" } } } ``` `article` Path - `./api/article/models/Article.settings.json` ```json= { "attributes": { "author": { "model": "user" } } } ``` #### Many-to-many 多對多 資料之間為多對多的連結關係,例如`restaurant`會有很多個`categories`,且`category`也會有相應的`restaurant`欄位 Example: `restaurant` Path - `./api/user/models/Restaurant.settings.json` ```json= { "attributes": { "categories": { "collection": "category", "via": "restaurants" } } } ``` `category` Path - `./api/article/models/Category.settings.json` ```json= { "attributes": { "restaurants": { "collection": "restaurant", "via": "categories", "dominant": true } } } ``` --- ## 4. 常用CLI(Command Line Interface)指令 ### `strapi new` 新建一個strapi專案(常用的為--quickstart,即為快速建立專案) 選項: ```javascript [--debug|--quickstart|--dbclient=<dbclient> --dbhost=<dbhost> --dbport=<dbport> --dbname=<dbname> --dbusername=<dbusername> --dbpassword=<dbpassword> --dbssl=<dbssl> --dbauth=<dbauth> --dbforce] ``` ### `strapi develop|dev` 在 `http://localhost:1337` 開啟==開發模式==的strapi頁面 加上 `/admin` 進入儀表板頁面 ### `strapi start` 在 `http://localhost:1337` 開啟==產品模式==的strapi頁面 加上 `/admin` 進入儀表板頁面 ### `strapi build` 將目前的strapi專案程式打包建構為產品版本 ### `strapi generate:<api名稱>` 可以在指令後面直接加上欄位相關的設定 例如 - `strapi generate:restaurant name:string` 會自動建立model, controller ...等相關資料夾 ### `strapi install <plugin插件名稱>` 將會安裝指定插件 例如 - `strapi install graphql` 就會安裝graphQL的插件(plugin)
{"metaMigratedAt":"2023-06-14T23:17:06.863Z","metaMigratedFrom":"YAML","title":"Strapi 概念架構介紹","breaks":true,"description":"Strapi brief introduction!","contributors":"[{\"id\":\"b742f78e-a93a-4d14-a695-c7a70118116d\",\"add\":8461,\"del\":6089}]"}
    4030 views