---
# System prepended metadata

title: Web API
tags: [System Architecture]

---

---
tags: System Architecture
---
Web API
===
* Read
    * [Understanding RPC Vs REST For HTTP APIs](https://www.smashingmagazine.com/2016/09/understanding-rest-and-rpc-for-http-apis/)
* Tool
    * [grpcio](https://pypi.org/project/grpcio/)
    * [wsjsonrpc](https://pypi.org/project/wsjsonrpc/)

# Introduction
* API definition
    * a **interface**
    * Provide by a specific software program (or a app) 
    * For other programs or people 
    * to use the specific software program
* What is API?
    * API is the key building-block for Interactive operation Web Platform
* Why you use API?
    * A data exchanging method for a data supplier of a specific problem
    * We don't need to rebuild everything by ourself
* Characteristics of Good APIs
    * Simple to use & Provide Useful Abstractions
    * Consistent
    * Expandability
    * Efficiency
* API Pattern
    * Definition
        * a definition of interface
        * Public a backend data of a serve to other app
    * Request / Response API
        * REST (REpresentational State Transfer)
        * RPC (Remote Procedure Call)
        * GraphQL
    * Event-driven API
        * WebHook
        * WebSocket
        * HTTP Streaming

# RESTful APIs
* Resource:
    * [Is REST Still a Relevant API Style?](https://nordicapis.com/is-rest-still-a-relevant-api-style/)
    * [Kenneth Lange's Blog:REST APIs](https://www.kennethlange.com/rest-apis/)
    * [Leonard Richardson: three-level REST Maturity Model](https://martinfowler.com/articles/richardsonMaturityModel.html)
* What is RESTful APIs? **Roy Fielding** get more deep about what made the internet software so successful in the first place and where it was lacking, and he finally list **six constraints**: 
    *  the six constraints called **Representational state transfer  (REST)**
    *  satisfies six constraints then it will exhibit a number of desirable properties (like scalability, decoupling, simplicity), which are absolutely essential in an Internet-sized system
    *   the constraints should be used as a checklist to evaluate new potential web standards
* RESTful API:
    * REST constraints lead to such great systems, why only used them for browsers and web sites?
    *  Above thinking led to the idea of RESTful Web Services, which are basically web services that satisfy the REST constraints, and are therefore well-suited for Internet-scale systems.
*  What exactly the REST mean?
    *  a server has a resource
    *  a client can request a "representation"(i.e. a description) of teh resource's "state"(i.e. data)
    *  client don't care about the server's internal implementation of the resource
    *  JSON (JavaScript Object Notation) format is often used for resource representation in REST
    *  REST "REpresentation State Transfer" just mean transferring these representational states between client and server
*  **6 REST constraints**:
    *  Client-Server
        *  there can be many different types of clients (web portals, mobile apps, BPM engines, etc.) that access the same server
        *  each of these can evolve independently of the other clients and the server (assuming that the interface between the clients and server is stable).
        *  This is seriously reduces the complexity of the server, as it doesn’t need to deal with UI stuff, which improves scalability.
        *  client-server is so ubiquitous today that we almost forget that there are other styles to consider (like event-based protocols)
        *   HTTP is almost always used when people develop RESTful Web Services,  but there is no constraint that forces us to use it(HTTP)
    *  Stateless
        *  stateless further simplify interactions between clients and servers
        *  all information about the client’s session is kept on the client, and the server knows nothing of it (so no cookies, session variables...)
        *  each request must contain all information necessary to perform the request(i.e. it cannot rely on any context information)
        *  server no longer needs to keep track of client sessions, resources between requests, and it does wonders for scalability because the server can quickly free resources after requests have been finished
    *  Cache
        *  The last constraint on the client-server communication is that responses from servers must be marked as cacheable or non-cacheable.
        *  An effective cache can reduce the number of client-server interactions, which contributes positively to the performance of the system. 
    *  **Uniform Interface**
        *  What really separate REST from other architectural styles is the Uniform Interface enforced by the fourth constraint.
        *  Uniform Interface decouples the interface from the implementation, which makes interactions so simple that it’s easy for somebody familiar with the style to understand it, even automatically
        *  The Uniform Interface constraint is made up of 4 sub-constraints:
            *   **Identification of Resources**
                *   The REST style is centered around resources. 
                *   resource is basically anything that can be named(static picture,real-time stock prices...)
                *   Each resource in a RESTful design must be uniquely identifiable via an URI and the identifier must be stable
                *   This means that each resource you want to expose through a RESTful web service must have its own URI.
            *   **Manipulation of Resources through Representations**
                *   client does not interact directly with the server’s resource. 
                *   server exposes a representation of the resource’s state
                *    we show the resource’s data (i.e. state) in a neutral format. This is similar to how the data for a web page can be stored in a database, but is always send to the browser in HTML.
                *    The most common format for RESTful web services is JSON, which is used in the body of the HTTP requests and responses
                *    this avoid a strong coupling between the client and server, so you can change the underlying implementation without affecting the clients.
            *   **Self-Descriptive Messages**:
                *   each message (i.e. request/response) must include enough information for the receiver to understand it in isolation
                *   Each message must have a media type (for instance, application/json or application/xml) that tells the receiver how the message should be parsed.
            *   **Hypermedia as the Engine of Application State**
                *   A web page is an instance of application state, hypermedia is text with hyperlinks. The hypermedia drives (i.e. engine) the application state. In other words, we click on links to move to new pages (i.e. application states).
                *    it basically means that we should use links (i.e. hypermedia) to navigate through the application
                *    It should work like a good web site where you just enter the URI and then you just follow the links that are provided on the web pages.
    *  Layered System
        *  client should only know the immediate layer it is communicating with, and not be aware of any layers behind it.
        *  This means that the client doesn’t know if it’s talking with an intermediate, or the actual server. 
    *  Code-On-Demand (optional)


# Python API Deployment
* [Docker + Django + Nginx + uWSGI + Postgres 基本教學 - 從無到有 ( Docker + Django + Nginx + uWSGI + Postgres Tutorial )](https://github.com/twtrubiks/docker-django-nginx-uwsgi-postgres-tutorial)
* Python 與前端的資料串接方式
    1. CGI
    2. FastCGI / WSGI ( Flup )
    3. uWSGI ( Django / Flask / Flup )
    4. Gunicorn ( Tornado )
* Python **WSGI** ( Web Server Gateway Interface)
        * [WSGI Servers](https://www.fullstackpython.com/wsgi-servers.html)
        * [WSGI](https://wsgi.readthedocs.io/en/latest/)
    * **Ｇateway**：a network node used in telecommunications that connects two networks with different transmission protocols together
    * **WSGI**：
        * the Web Server Gateway Interface 
        * a specification that describes how a web server communicates with web applications
        * a specification that describes how web applications can be chained together to process one request
        * WSGI is a Python standard described in detail in [PEP 3333](https://www.python.org/dev/peps/pep-3333/)

    * WSGI、flup、fastcgi、web.py的關聯
        * **Apache**：相當於一個請求代理，根據配置，把不同的請求轉發給不同的服務器處理，例如靜態的文件請求自己處理，這個時候它就像一個web服務器，對於fastcgi / python 這樣的請求轉發給 flup 這樣的服務器/網關進行處理
        * **Flup**：一個用python寫的web服務器，也就是cgi中所謂的 **Server/Gateway**，它負責接受 apache 轉發的請求，並調用應用程序，並將應用處理的結果返回到apache
        * **fastcgi**：
            * apache 的一個模塊，雖然 flup 可以作為一個獨立的 web 服務器使用，但是對於瀏覽器請求處理一般都交給 apache 處理，然後由 apache轉發給 flup 處理，
            * fastcgi 把 apache 的跟flup聯繫起來，通過環境變量以及 socket 將 client request 傳送給 flup 並接收 flup 返回的結果
        * **web framework**：django, flask or web.py
            * 處理瀏覽器的輸入輸出，還有cookie，session，模板...等各種各樣的問題
        * **WSGI**：
            * WSGI就是一個規範，他規範了 flup 這類服務的一些規格
            * 讓各種服務器都可以執行，

## Flask API
* [Flask - RESTful API server](https://hackmd.io/@hackerYM/ByIkoFPsm)

```python
# app.py
from flask import Flask

UPLOAD_FOLDER = 'D:/Temp2'

app = Flask(__name__)
app.secret_key = "secret key"
app.config['UPLOAD_FOLDER'] = './'
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024



# main.py
import os
#import magic
import urllib.request
from app import app
from flask import Flask, flash, request, redirect, render_template
from werkzeug.utils import secure_filename

ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'])

def allowed_file(filename):
	return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

def MockResponse(filename):
    # 在這裡呼叫 AI 相關功能，回傳 JSON 格式字串
    return "{ 'name': 'JSON result sample' }"
	
@app.route('/')
def upload_form():
	return render_template('upload.html')

@app.route('/', methods=['POST'])
def upload_file():
	if request.method == 'POST':
        # check if the post request has the file part
		if 'file' not in request.files:
			flash('No file part')
			return redirect(request.url)
		file = request.files['file']
		if file.filename == '':
			flash('No file selected for uploading')
			return redirect(request.url)
		if file and allowed_file(file.filename):
			filename = secure_filename(file.filename)
            
            #將檔案儲存至磁碟，在這裡請指定其他程式可以抓到的地方
			file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            
            #將結果的 JSON 回傳
			response = app.response_class(response=MockResponse(filename), status=200, mimetype="application/json")
			return response
		else:
			flash('Allowed file types are txt, pdf, png, jpg, jpeg, gif')
			return redirect(request.url)
    
if __name__ == "__main__":
    app.run()
    
    
# wsgi.py
import sys
sys.path.insert(0, '/var/www/flaskApp')


from main import app as application
```

##  Django REST Framework
* Resource:
    * [Test Driven Development of a Django RESTful API](https://realpython.com/test-driven-development-of-a-django-restful-api/)
    * [Let’s build an API with Django REST Framework](https://medium.com/backticks-tildes/lets-build-an-api-with-django-rest-framework-32fcf40231e5)
    * [how to unit test file upload in django](https://stackoverflow.com/questions/11170425/how-to-unit-test-file-upload-in-django)
* Quick View:
    * [Train/predict simple machine learning model with Django REST.](https://medium.com/@mahdi04/train-predict-simple-machine-learning-models-with-django-rest-76ce46bf2868)

#### Python API with System Server:
* [uWSGI](https://www.fullstackpython.com/uwsgi.html)
* [wfastcgi.py](https://pypi.org/project/wfastcgi/)
* [如何將 Django 架設在 IIS 上](https://ithelp.ithome.com.tw/articles/10210064)
* Apache Only:
    * [mod_wsgi](https://github.com/GrahamDumpleton/mod_wsgi)
* Flup：Python 寫的 Server/Gateway，WSGI 算是這一類軟體的統一規格。
...