1

I'm working on a Flask example that takes blog posts and adding them to a database through a RESTful service.

Prior to implementing the RESTful service, I was adding blog posts to a local database by doing the following:

@main.route('/', methods=['GET', 'POST'])
def index():
    form = PostForm()
    if current_user.can(Permission.WRITE_ARTICLES) and \
            form.validate_on_submit():
        post = Post(body=form.body.data,
                    author=current_user._get_current_object())
        db.session.add(post)
        return redirect(url_for('.index'))

Now that I've gotten to the RESTful service section, the following to_json() and from_json() functions have been to the Post model:

//Convert a post from JSON
//Class Post(db.Model)
def to_json(self):
        json_post = {
            'url': url_for('api.get_post', id=self.id, _external=True),
            'body': self.body,
            'body_html': self.body_html,
            'timestamp': self.timestamp,
            'author': url_for('api.get_user', id=self.author_id,
                              _external=True),
            'comments': url_for('api_get_post_comments', id=self.id,
                                _external=True),
            'comment_count': self.comments.count()
        }
        return json_post

//Create a blog post from JSON
//Class Post(db.Model)
@staticmethod
def from_json(json_post):
    body = json_post.get('body')
    if body is None or body == '':
        raise ValidationError('post does not have a body')
    return Post(body=body)

The following inserts a new blog post in the database:

//POST resource handler for posts
@api.route('/posts/', methods=['POST'])
@permission_required(Permission.WRITE_ARTICLES)
def new_post():
    post = Post.from_json(request.json)
    post.author = g.current_user
    db.session.add(post)
    db.session.commit()
    return jsonify(post.to_json()), 201, \
        {'Location': url_for('api.get_post', id=post.id, _external=True)}

Would really appreciate it if someone could explain how these functions work with each other. My understanding of it all is that a blog post is typed up on a client device and in order to send it to the web service, the to_json function is called to convert the post to JSON. Once the web service receives the JSON version of the blog post, the from_json function is called to convert the JSON post back to its original state. Is that correct?

Edit: Just re-read the page and I think my understanding was reverse of whats actually happening. In order to get a blog post from the web service, the to_json function is called to convert the data to JSON. Then on the client side, the from_json function is called to convert the data back from JSON.

Brosef
  • 2,945
  • 6
  • 34
  • 69

1 Answers1

1

Your edit is correct. A common response format for a REST API is JSON, which is why the the response is converted "to JSON" when returning.

Also a common header for sending data to a REST API is application/json, which is why the code converts the received data "from JSON".

nivix zixer
  • 1,611
  • 1
  • 13
  • 19
  • In the `new_post` function, does the `request.json` parameter contain the JSON data of the post that is being sent to the web service? Thats what I'm assuming since `from_json` is getting called and there is no other parameter in the function that would hold the JSON data. – Brosef Jul 21 '15 at 03:15
  • Yes, `request.json` looks in the POST header for any data of type `application/json` – nivix zixer Jul 21 '15 at 03:16
  • Sorry, I'm pretty new to python and flask. What exactly do you mean by the POST header and `application/json` – Brosef Jul 21 '15 at 03:20
  • No need to apologize, everyone is new at some point. :) What I am speaking of is outside the scope of Python or Flask; I'm referring to HTTP requests. Do you know the difference between a GET request and a POST request? – nivix zixer Jul 21 '15 at 03:23
  • My understanding is basic. GET is a type of request you send when you want to fetch something from the server, while POST is a type of request when you want to store something in the server. – Brosef Jul 21 '15 at 03:29
  • Basically, yes. A GET request can contain data in the url, but a POST request has it's data in the request header. The data can be different types (eg: `raw`, `application/x-www-form-urlencoded`, etc.). Your flask app expects data in the POST request to be sent as JSON, therefore it will have the `application/json` content-type header set. Read this for more help: http://stackoverflow.com/a/26717908/4774955 – nivix zixer Jul 21 '15 at 03:49
  • What I find confusing is that the `new_post` function is calling the `from_json` function, meaning the data it is receiving has already been converted to JSON. This leads me to assume that `new_post` is meant to be server side. However, the book doesn't provide a separate function showing the conversion of the data to JSON on the client. The client can't use the same `to_json` function shown above, correct? That function should only be used by the server as I understand it. – Brosef Jul 22 '15 at 00:57
  • See that bit of code, `request.json`? That represents a request from the user, specifically all the data sent from the user as a json object. The server decodes the json data it received from the client via the `from_json` method. – nivix zixer Jul 22 '15 at 04:05
  • gotcha, but my question is where does the data from the user get converted to a json object? – Brosef Jul 22 '15 at 05:10
  • `request` is a Flask object from class `Request`. Nothing can explain it better than the source: https://github.com/mitsuhiko/flask/blob/master/flask/wrappers.py#L99 – nivix zixer Jul 22 '15 at 14:42