Date post: | 18-Feb-2017 |
Category: |
Software |
Upload: | make-school |
View: | 2,633 times |
Download: | 0 times |
BUILDING A SERVER WITH FLASK
AGENDA
Client-Server Communication
Building a Custom Backend
Flask / MongoDB
Defining a Server API
Development Technique
CLIENT-SERVER COMMUNICATION
CLIENT-SERVER COMMUNICATION
1. Serialization
2. Network Requests
SERIALIZATION
Transforming in-memory object graphs into a linear sequence of data that can be stored on disk or sent over a network
SERIALIZATION
User User
Product Product
Product
Product
Object Graph Serialized Document
{ UserID: 934235, Username: "Ben-G", Purchases: [ { ProductID: 1278123, Price: 99, Name: "Apple TV" } ], [ { ProductID: 7238483, Price: 299, Name: "Kitchen Set" } ],}
Serialization
SERVER ARCHITECTURE & REQUEST LIFECYCLE
CLASSIC 3-TIER ARCHITECTURE
Client is a “thin client” only taking care of
representation
The actual logic of the application is
implemented on the server
Representation
Business Logic
Persistence
Client
Server
DB
Network Requests
Insert, Select, Update, Delete
MODERN 3-TIER ARCHITECTURE
Client
Server
DB
HTTP Requests / Responses
Insert, Select, Update, Delete
Client has become a “fat client”, in many cases
implementing a significant amount of business logic
Amount of business logic on the server can vary
In Apps that use the Parse Framework, for example,
the Backend only acts as a proxy for the DB
In contrast Twitter has a huge amount of server
logic and less logic on the clientBusiness Logic
Representation
Business Logic
Persistence
Client
Server
DB
getUsers:HTTP Request
GET http://myApp/Users
function getUsers { return db.user.find()}
DB RequestUser1User2User3User4
HTTP Response
[ { username: “Test1”, age: 20 }, { username: “Test2”, age: 23 }, …]
User
User
User
User
Parse into Objects
ClientDB
1
2
3
4
5
67
CLIENT-SERVERREQUEST CYCLE
ANATOMY OF AN HTTP REQUEST [1]
HTTP Method
URI
Header Fields(Authorization, Content-Type)
Body
BUILDING A CUSTOM BACKEND
WHY?
Education: Writing a custom backend will help you understand client server communication
Flexibility: Frameworks, such as Parse, don’t provide the full flexibility of custom solutions, in many cases it will be necessary to write a custom backend
HOW?
Flask: a simple framework for web applications written in python
MongoDB: a document based database
RELATIONAL VS DOCUMENT BASED DB BRIEF OVERVIEW
RELATIONAL DB
Strongly denormalized data model → low redundancy
Besides IDs we don’t have redundant information, e.g. product name is only stored in one place
If we have a username and want to get the name of a purchased product we need to JOIN all three tables
UsernameUserID
USER
Ben-G934235
USER_PURCHASES
ProductIDUserID
1278123934235
7238483934235
232133123233
123233 Daniela
PRODUCT
PriceProductID
991278123
2997238483
679123233
Name
Apple TV
Kitchen Set
Expensive Shoes
RELATIONAL DBStrict Schema → Application knows exact format of data stored in DB
Normalized model makes writes easier. Information only needs to be updated in one place
Frequent JOIN operations are expensive
Strict Schema → Even simple changes need schema migration
DOCUMENT BASED DBMostly strongly denormalized, this means a lot of
redundant information is stored
E.g.: Product Information could be stored directly in
the purchase record, product information is stored
with every single purchase
Faster reading, slower writing
MongoDB has a flexible schema, that means fields
can be added to / omitted from documents
{ UserID: 934235, Username: "Ben-G", Purchases: [ { ProductID: 1278123, Price: 99, Name: "Apple TV" } ], [ { ProductID: 7238483, Price: 299, Name: "Kitchen Set" } ],}
DOCUMENT BASED DB
Top level hierarchy consists of collections
Collections contain documents
DB User
User Collection
User
User User
Location
Location Collection
Location
Location Location
DOCUMENT BASED DBNo Schema → It’s easy to change the data model of an existing application without needing a migration
Denormalized model makes reads faster, there’s no need to join different documents
Write operations can be expensive as denormalized data needs to be updated in multiple places
No Schema → You need to handle different schema versions on an application level
FLASK
FLASK
A python framework for building web servers
Allows to map different HTTP requests to python functions
Provides many libraries that we’ll use to speed up development
DEFINING A SERVER API
DEFINING A SERVER API
Many different ways to structure a backend server
Will use the one that is currently most common: RESTful Web Services
RESTFUL WEB SERVICES
Server does not store state of client connection between requests, all the information necessary to service the request is provided by client. There are no server-side sessions.
Web Service is structured based on resources e.g. a User resource, a Product resource
RESTFUL WEB SERVICES
Each request consists of:
URL - identifies the affected resource
HTTP Method (GET, PUT, etc.) - defines the action
on the resource
Request Body - can contain additional information
on how resource should be affected
RESTFUL WEB SERVICE EXAMPLE
Based on: http://en.wikipedia.org/wiki/Representational_state_transfer
Resource GET PUT POST DELETE
Collection URI, e.g.
http://planly.com/trips
Return list of trips with
details or list of trip URIs
Replace entire collection with
another collection
Create a new entry in the collection
Delete the entire
collection
Element URI, e.g.
http://planly.com/trips/18
Return a representation
of specified item
Replace specified item
-Delete the
specified item
DEVELOPMENT TECHNIQUE
TDDTDD (Test Driven Development) is an approach to
Software Development in which development
starts by writing automated tests before writing
application code
Tests specify the behavior of the application
TDDDevelopment Cycle with TDD:
1. Write a test for a software feature
2. Run test - test will fail
3. Implement feature
4. Run test - test should succeed
5. Refactor code for implementation
6. Run test - test should succeed
This is often referred to as Red → Green → Refactor
TDD - EXAMPLE TEST CASE
def test_incorrect_credentials(self): response = self.app.get('/user/', headers=self.generate_auth_header( 'wrongusername', 'andpassword') )
self.assertEqual(response.status_code, 401)
SUMMARY
SUMMARYMany Applications (including ours) use a 3-Tier architecture with a
lightweight server
We are going to implement a server with flask that uses the
document based DBMS MongoDB
We are going to implement a RESTful Web Service that will be
consumed by our iOS application
We will implement the server with TDD, writing tests first and code
second
GETTING STARTED
GETTING STARTED
The dashboard contains a writeup on how to setup your development environment
It also contains a starter project for your backend server
REFERENCES