iT邦幫忙

2023 iThome 鐵人賽

DAY 24
0
Mobile Development

單人開發者之路:React Native 與 Expo 帶你從開發到上架系列 第 24

Day 24 - 使用 Fetch 和 MockAPI 模擬真實資料 feat.環境變數

  • 分享至 

  • xImage
  •  

在APP功能中,其實許多資訊
都會經過後端API做伺服器驗證
以Facebook為例,以下功能都會向後端伺服器驗證取回結果

  • 登入驗證、忘記密碼
  • 重設密碼
  • 動態、貼文、通知
  • 按讚、留言、分享

本篇要來分享
使用fetch語法呼叫MockAPI
讓你的APP能模擬取得後端伺服器資訊

在搭上「環境變數」(下稱env)
全域使用API網址

Fetch

介紹

mdn技術文件介紹:https://developer.mozilla.org/zh-TW/docs/Web/API/Fetch_API/Using_Fetch
React Native 官方推薦介紹:https://reactnative.dev/docs/network

Fetch 是一個用於發送網路請求(Request)和處理回應(Response)的 JavaScript API
通常用於獲取、發送和處理服務器上的資源。

Fetch 提供了更簡單和強大的方式來處理網路請求
並能夠處理 JSON、文件、圖片等各種數據類型。
使用 Fetch,你可以輕鬆地向服務器發送 GET、POST、PUT、DELETE 等不同類型的請求
並處理服務器的回應。
Fetch 是基於 Promise 的,這使得它更容易處理異步操作,並提供了更好的錯誤處理機制。

後端工程師需要提供甚麼API資訊

如果你不是像我一個人開發前後端的話...

當前端工程師使用 Fetch 或其他 HTTP 請求來呼叫後端 API 時
後端工程師通常需要提供以下資訊給前端工程師:

  1. API 端點 (Endpoint):API的網址(URL)
    fetch最重要的參數之一
    例如:https://example.com/api/users
  2. HTTP 方法(Method):前端工程師需要知道應該使用哪種 HTTP 方法來執行特定的操作
    例如 GET、POST、PUT、DELETE 等。
    這表示是要從 API 中取得資料、新增資料、更新資料還是刪除資料。
    HTTP Method設定參考MDN文件
  3. HTTP 標頭(Headers):這包括任何必要的請求標頭
    例如驗證、授權標頭、內容類型標頭等。
    這些標頭通常在 fetch 或其他 HTTP 請求的選項中設定
  4. HTTP 主體(body):對於某些操作,例如 POST 或 PUT
    可能需要在請求主體中傳遞資料,通常以 JSON 格式。
    後端工程師需要確定如何組織和解析這些資料
  5. HTTP 回應(Response):前端工程師需要知道後端 API 回應的資料格式
    通常是 JSON 或 XML
    這有助於前端工程師在收到回應後解析資料。
    (不建議使用XML格式回傳,在React Native需安裝第三方套件才能快速解析)
  6. HTTP 狀態碼(Status Codes):前端工程師需要知道可能的 HTTP 狀態碼
    以便根據不同的狀態碼處理回應。
    例如,200 表示成功,404 表示未找到資源,500 表示伺服器錯誤等

其他使用資訊可以參考mdn官方:fetch Request 可用的設定值

使用方法

使用Fetch不需安裝任何項目,因為這是JavaScript內置API

基本用法

借一下官方的範例
最簡單的方式就是傳入網址參數,即可取得資料

const getMoviesFromApi = () => {
  return fetch('https://reactnative.dev/movies.json')
    .then(response => response.json())
    .then(json => {
      return json.movies;
    })
    .catch(error => {
      console.error(error);
    });
};

fetch進階共用方法

提供一支簡單的function範例

export default async function fetchDataAsync(apiRouteUrl, data, method) {
  try {
    const requestOptions = {
      method: method,
      headers: {
        "Content-Type": "application/json", //客戶端告訴伺服器實際發送的資料類型
        Accept: "application/json", //客戶端告訴伺服器實際回傳的資料類型
        Connection: "close", //叫用後關閉連線
      },
    };

    if (method.toUpperCase() !== "GET" && typeof data === "object") {
      requestOptions.body = JSON.stringify(data);
    }

    const response = await fetch(
      `https://reactnative.dev/${apiRouteUrl}`,
      requestOptions
    );

    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }

    const responseData = await response.json(); //限定回傳一定為Json格式
    return responseData;
  } catch (error) {
    console.error("An error occurred:", error);
    throw error;
  }
}

※若HTTP方法是GET,不可提供body屬性
否則會拋出錯誤Request with GET/HEAD method cannot have body.

取得人員資訊(GET用法)

Day 16的滑動選單內容,原本是以假資料代替
加上useEffect效果後,進入畫面後向後端API取得資料
將API回傳的人員資訊清單,更新至清單中

使用上方fetch共用方法 fetchDataAsync 實作範例
GET方法時,不需帶入任何參數,就能順利取得資料集

const [data, setData] = useState(initialData);

useEffect(() => {
  fetchDataAsync("api/App/v1/GetUserData", null, "GET")
  .then((userDataList) => {
    setData(userDataList);
  });
}, []);

登入確認使用API驗證(POST用法)

Day 10的登入驗證功能,稍作修改
就能利用API驗證
確認這個使用者是否能正常登入

使用上方fetch共用方法 fetchDataAsync 實作範例
可以看到在POST方法時,必須傳遞物件參數
讓後台能使用資訊驗證

function onLogin() {
  fetchDataAsync(
    "api/App/v1/PostData",
    {
      Account: "123",
      Password: "456",
    },"POST"
  )
    .then((json) => {
      if (!json.Success) {
        Alert.alert("伺服器錯誤訊息", json.Message);
      } else {
        Alert.alert("伺服器完成訊息", "登入成功");
        navigation.navigate("Index");
      }
    });
}

MockAPI

官方網站:https://mockapi.io/

介紹

Mock API(模擬 API)是一種工具或技術,用於在軟體開發過程中模擬後端伺服器的行為
以便在前端應用程式的開發和測試期間使用。
這種方法的主要目的是使開發者能夠在不連接到實際後端伺服器的情況下進行開發和測試。

在一個專案裡,一定會搭著前端與後端工程師
若後端工程師沒有時間製作API,不彷先使用MockAPI模擬取得資料

「我不確定工程師能不能擠出時間」

使用方法

網站點選Get Started,需要註冊網站會員才能使用功能
註冊完後會看到Project與「+」的圖案,按下「+」可以新增API專案
新增完成後應該會長這樣,接著按下「New Resource」製作第一支API

https://ithelp.ithome.com.tw/upload/images/20230928/20130821KLxV4B0AT0.png

要注意一點的是
免費版只能設定Schema (optional),且只能回傳陣列類型
將你想要回傳的欄位設定好

參考圖片上方,我已預先設定GetUser API
GetUser連結點下去就是API路由網址
https://64f622702b07270f705e3258.mockapi.io/GetUser
回傳陣列內容: [{"UserName":"我是API來的使用者","id":"1"}]
也可自行設定資料數量(GetUser下方有個拉條可以拉)

測試有回傳成功,代表你學會MockAPI了👏

 fetch('https://64f622702b07270f705e3258.mockapi.io/GetUser')
  .then(response => response.json())
  .then(json => {
    console.log(json);
  })

※目前MockAPI只提供四種HTTP Method提供測試使用:GET、POST、PUT、DELETE

env 環境變數

Expo官方講解:https://docs.expo.dev/guides/environment-variables/

介紹

環境變數指的是
整個APP都能讀取這項變數
通常用在API網址、版本號、不常變動的資訊
讓你在開發時,無須透過元件傳遞,直接使用該常數
在ASP.NET開發類似Web.config的存在

安裝

若你是Expo 49版本,無需安裝任何套件,該版本內置讀取環境變數

Expo CLI now has built-in support for environment variables in Metro

若為其他版本,需安裝 react-native-dotenv
安裝指令:npx expo install react-native-dotenv

使用方法

在專案最外層新增.env

檔案內容範例如下
Expo 49版規定前方要加EXPO_PUBLIC_ 才能讀取

EXPO_PUBLIC_API_URL="https://reactnative.dev/"
EXPO_PUBLIC_API_KEY="qaz555"
EXPO_PUBLIC_APP_VERSION="1.0.0"

若在開發中新增環境變數
記得終端機Ctrl+c,再重啟APPnpx expo start

終端看到以下資訊,就代表讀取成功

Starting project at D:\...
env: load .env
env: export API_URL API_KEY APP_VERSION

.gitignore設定忽略.env檔案

因為環境變數往往會儲存API網址
得防止API被惡意呼叫及利用

修改Expo忽略部分,加上.env

# Expo
.expo/
dist/
web-build/
.env

使用.env中的變數

範例:在畫面放上APP版本號

const appversion = process.env.EXPO_PUBLIC_APP_VERSION;
//其餘程式碼省略
<Text>{appversion}</Text>

修改fetch進階共用方法

參考上方fetchDataAsync function,可以看到API網址是寫死的
套入環境變數後,日後API網址若有調整需求
只要修改環境變數即可🤭

const apiUrl = process.env.EXPO_PUBLIC_API_URL;

export default async function fetchDataAsync(apiRouteUrl, data, method) {
//...其餘程式碼省略

const response = await fetch(
     `${apiUrl}/${apiRouteUrl}`,
     requestOptions
);

//...其餘程式碼省略
}

開發環境、正式環境變數分配

為了區隔測試主機API與正式主機API變數不同
往往會使用多個環境變數檔

先附上可使用的env檔列表:
https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use
這裡只介紹切換Prod環境部分
其餘環境檔得看實際專案需求做增減

新增Prod正式版本env

一樣在專案外層新增.env.production.local
試著調整正式版本內容

EXPO_PUBLIC_API_URL="https://docs.expo.dev/"
EXPO_PUBLIC_API_KEY="qaz777"
EXPO_PUBLIC_APP_VERSION="1.2.0"

在Package.json 加上start:prod標籤及內容

  "scripts": {
    "start": "expo start",
    "start:prod": "NODE_ENV=prod npx expo start",
    "android": "expo run:android",
    "ios": "expo run:ios",
    "web": "expo start --web"
  },

APP執行指令修改為
npm run start -prod

只要終端機看到讀取的環境檔為production
Expo就會使用正式環境的變數去執行APP

Starting project at D:\...
env: load .env.production.local .env
env: export EXPO_PUBLIC_API_URL EXPO_PUBLIC_API_KEY EXPO_PUBLIC_APP_VERSION

結語:
到這裡,你已經學會如何使用fetch
呼叫後端API取得資訊
還學會運用環境變數管理APP專案

本系列的開發環節,到這邊正式告一段落
接下來的篇章皆為React Native Expo APP專案建置、上架為主
將自己的APP放到商店後,圓滿完成屬於你的第一支APP🥳


上一篇
Day 23 - Expo Location 實作地理位置追蹤功能
下一篇
Day 25 - 使用Expo專案建置你的第一支Android APP
系列文
單人開發者之路:React Native 與 Expo 帶你從開發到上架30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言