How to integrate REST API in React application
Tags: javascript, react, rest
Published: 2020-03-30 21:42:26

This post describes the way to integrate REST API to a React application.
The sample codes are based on the source code when I joined DeveloperWeek 2020 hackathon.
- https://www.developerweek.com/events/hackathon/

# Fetch API

Fetch API is standard  API to access HTTP resources and it is similar to XMLHttpRequest API.
For details, see the following reference.
- https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API



# Common class for API

The following code is a common class named as "APICommon" to call get, post, put and delete method for REST API.

Basically, this class has get, post, put and delete functions, each function is corresponding to each http method.

```javascript
let setting = undefined
let endPoint = ""
const mode = "cors"
const credential = "omit"
const headers = new Headers({
  "Content-type": "application/json",
})

export default class ApiCommon {
  static Method = {
    GET: "GET",
    POST: "POST",
    PUT: "PUT",
    DELETE: "DELETE",
  }

  static init(serverSetting) {
    setting = serverSetting
    endPoint = `${setting.url}/${setting.base}`
  }

  static async get(path) {
    return doFetch(
      getApiUrl(path),
      getOption()
    )
  }

  static async post(path, request) {
    return doFetch(
      getApiUrl(path),
      getUpdateOption(ApiCommon.Method.POST, request)
    )
  }

  static async put(path, request) {
    return doFetch(
      getApiUrl(path),
      getUpdateOption(ApiCommon.Method.PUT, request)
    )
  }

  static async delete(path, request) {
    return doFetch(
      getApiUrl(path),
      getUpdateOption(ApiCommon.Method.DELETE, request)
    )
  }
}

const getApiUrl = (path) => {
  const apiUrl = `${endPoint}${path}`
  return apiUrl
}

const getOption = () => {
  const option = {
    method: ApiCommon.Method.GET,
    mode: mode,
    credential: credential,
    headers: headers,
  }
  return option
}

const getUpdateOption = (method, request) => {
  const option = {
    method: method,
    mode: mode,
    credential: credential,
    headers: headers,
    body: JSON.stringify(request),
  }
  return option
}

const doFetch = async (path, option) => {
  let ok = false
  let status = -1
  console.debug("API-request:", path, option)
  return await fetch(path, option)
    .then(response => {
      ok = response.ok
      status = response.status
      return response.text()
    })
    .then(text => {
      const json = text !== "" ? JSON.parse(text) : {}
      console.debug("API-response:", path, status, { json })
      return { ok, status, json }
    })
    .catch(error => {
      console.debug("API-error:", path, { error })
      throw error
    })
}
```

# How to use common API class
## Initialize

Call to "ApiCommon.initalize" method in your entry point jsx file like App.jsx.

URL and REST API base part are configured in a json file like "setting.json".

```json
{
  (snip)
  "server": {
    "url": "http://localhost:7000",
    "base": "detra"
  }
  (snip)
}
```



## Wrapper class for a resource of REST API server
The following code is an example to access "User" resource of REST API server.

- Each function name is corresponding to one REST API name.
- Every function is "async" function by using "await"
- To use APICommon is just easy like below.
  - login ... post method to login. `ApiCommon.post("/login", request)`
  - create ... post method to create user. `ApiCommon.post("/users", request)`
  - list ... get method to retrieve user list. `ApiCommon.get("/users")`

```javascript
import ApiCommon from "./apiCommon"

export default class UserApi {
  static login = async (request) => {
    return ApiCommon.post("/login", request)
  }

  static create = async (request) => {
    return ApiCommon.post("/users", request)
  }

  static list = async () => {
    return ApiCommon.get("/users")
  }

  static get = async (userId) => {
    return ApiCommon.get(`/users/${userId}`)
  }

  static update = async (userId, request) => {
    return ApiCommon.put(`/users/${userId}`, request)
  }

  static delete = async (userId) => {
    return ApiCommon.delete(`/users/${userId}`, {})
  }
}
```

# Helpful tools for test

I introduce two tools for developing REST API.

## Advanced REST Client
"Advanced REST Client" is a GUI tool for REST API server.
- https://advancedrestclient.com

You can test your and 3rd party REST API with using GUI.
![arc-image](https://install.advancedrestclient.com/images/hero-image-light@0.75x.png)
 
## Json Utils - online json to code converter 
Json Utils is an online converter site from json to several programing language.
- https://www.jsonutils.com/

You can generate class/object source code from input json format.
It is also helpful to develop from sample json response.