snippetpythonflaskMinor
RESTful APIs (Create, Read) with flask-restful
Viewed 0 times
apisflaskcreatereadwithrestful
Problem
I wrote this simple API to be able to send logs from the client to MongoDB. Even though this works and fits my need, I would like to point out some concerns that I have regarding the following:
```
from flask import Flask, jsonify, request, Response
from flask_restful import Resource, Api
from pymongo import MongoClient
import json
app = Flask(__name__)
api = Api(app)
USER = "user"
PASS = "pw"
MONGO_URI = 'mongodb://%s:%s@test.mlab.com/test' % (USER, PASS)
PORT = 19788
def db_conn():
client = MongoClient(MONGO_URI, PORT)
return client
def insert_record(args):
client = db_conn()
replycode = 0
try:
db = client['test']
posts = db.users
posts.insert(args)
except:
replycode = 1
return replycode
def select_record(args={}):
client = db_conn()
db = client['test']
result = db.users.find(args)
return result
class CreatUser(Resource):
def post(self):
try:
content = request.get_json()
if "Vehicle" not in content:
return jsonify({"Result": "Vehicle number not in passed arguments"}), 400
else:
vehicle = content['Vehicle']
reply = insert_record(content)
if reply == 0:
return jsonify({"Result" : "Successfully inserted user: " + vehicle}), 201
else:
return jsonify({"Result" : "Failed to insert data. Check logs for more details"}), 400
except Exception as e:
return jsonify({'Error' : str(e)}), 500
class ViewUser(Resource):
def get(self):
from bson import json_util
results = select_record()
final = []
for result in results:
result.pop("_id")
final.append(result)
- Is it efficient to be calling the instance of MongoClient for every request?
- Do I need to close the instance of MongoClient after the request is successful?
- A more Pythonic way to return responses?
```
from flask import Flask, jsonify, request, Response
from flask_restful import Resource, Api
from pymongo import MongoClient
import json
app = Flask(__name__)
api = Api(app)
USER = "user"
PASS = "pw"
MONGO_URI = 'mongodb://%s:%s@test.mlab.com/test' % (USER, PASS)
PORT = 19788
def db_conn():
client = MongoClient(MONGO_URI, PORT)
return client
def insert_record(args):
client = db_conn()
replycode = 0
try:
db = client['test']
posts = db.users
posts.insert(args)
except:
replycode = 1
return replycode
def select_record(args={}):
client = db_conn()
db = client['test']
result = db.users.find(args)
return result
class CreatUser(Resource):
def post(self):
try:
content = request.get_json()
if "Vehicle" not in content:
return jsonify({"Result": "Vehicle number not in passed arguments"}), 400
else:
vehicle = content['Vehicle']
reply = insert_record(content)
if reply == 0:
return jsonify({"Result" : "Successfully inserted user: " + vehicle}), 201
else:
return jsonify({"Result" : "Failed to insert data. Check logs for more details"}), 400
except Exception as e:
return jsonify({'Error' : str(e)}), 500
class ViewUser(Resource):
def get(self):
from bson import json_util
results = select_record()
final = []
for result in results:
result.pop("_id")
final.append(result)
Solution
The
Also you've mentioned your
1) To deal with user resource you should include it in the uri in pluralize form and distinguish actions you are performing by standard http codes, like the following:
2) when you a new user is created it is a good practise to return
3) "Failed to insert data. Check logs for more details" - it doesn't look like a
Hope this helps
MongoClient was designed to be instantiated once per app life cycle, so this is redundant. You should try to reuse MongoClient instances as much as possible. Basically the only reason to create a new instance is if you want to configure it in a different way.Also you've mentioned your
API is supposed to be RESTful, so a few notes here:1) To deal with user resource you should include it in the uri in pluralize form and distinguish actions you are performing by standard http codes, like the following:
/api/users POST - to create a new user /api/users/{userId} GET - to fetch an existing one by userId2) when you a new user is created it is a good practise to return
201 (Created) http code together with the full url to fetch the user which has been just created, like: http://yourdomain.com/api/users/{userId}3) "Failed to insert data. Check logs for more details" - it doesn't look like a
400 Bad Request, as the user didn't make any mistake with input params. I suppose it must be either 500 (if the issue is related to something like a database error for example) or 403 Forbidden if any of implicit domain rules has been violatedHope this helps
Context
StackExchange Code Review Q#151824, answer score: 3
Revisions (0)
No revisions yet.