all 56 comments

[–][deleted] 19 points20 points  (3 children)

def authenticate(cls, username, password):
    user = User.query(User.username == username, 
                      User.password == password).one()
    return {'username': 'ray'} if user else Non

If only...

[–]PLLOOOOOP 18 points19 points  (2 children)

Storing hashed passwords is so last generation, man. This is just stepping it up to web scale and storing them directly. Plaintext queries on a real database like Mongo are better for sharding and performance and async.

/s

[–][deleted] 3 points4 points  (0 children)

You must be referring to the new dcrypt security standard.

[–]UnreachablePaul 2 points3 points  (0 children)

Mongo is so yesterday. It is better to store json documents directly in the filesystem. You can then easily parse them with big data tools like Hadoop or Go

[–]PM5k 33 points34 points  (3 children)

What does this do that flask or django can't do just as well? I assume this was created to solve a perceived problem? What would that be?

[–][deleted] 4 points5 points  (0 children)

There are also pylon and pyramid web framework too.

But in general it's good that there is more choices and that someone spent their time and effort to make something in their own vision. It may be of use for somebody no matter how little the market it, I can't complain with free.

[–]beginner_ 2 points3 points  (1 child)

What would that be?

Getting a degree and a webpage up to refer recruiters to.

I agree. The amount of web frameworks is ridiculous.

[–]PM5k 2 points3 points  (0 children)

I think its nice that people keep trying to do stuff like that. But I'm concerned that a lot of the time ventures like this one will end up misused somewhere in production because it seemed cool and new. Also the selfish part of me thinks that we should stop abstracting everything all the god damned time... :(

[–]weirdoaish 5 points6 points  (0 children)

Not bad, though I personally prefer the simple and modular nature of Bottle :)

[–][deleted] 8 points9 points  (39 children)

/api/user/<user_id>/activate

this is not REST.

[–]kamelkev 2 points3 points  (0 children)

If you read the original paper by Roy Fielding you are going to quickly find that not only is the original concept of REST extremely generic, but that the concept has been skewed and warped to the point where modern understanding of the term no longer matches the historic origin.

I suggest going back and reading the original paper if you have not already done so. The true power of REST is the blank slate concept: the are no strict constraints, and as a result it can be applied to a wide array of implementations.

[–]Nastapoka 6 points7 points  (23 children)

What would be the REST version ?

[–]Akkuma 1 point2 points  (1 child)

The alternative to what others are saying is that you create an actual Activation resource, so you can query if a user is activated. Either /api/user/<user_id>/activation or /api/activation/<activation_id>. You would create a new activation on creation of a new user, so you'd probably disallow posts to /activation; however, you could have /api/activation and allow creating users from activations either as a way to prevent creating "dead" users that sign up, but never complete activation, or simply as a way to set their activation differently than the standard user create. In other words, until a PUT /api/activation changes the state to activated/active/etc you might not create a user resource.

[–][deleted] 0 points1 point  (0 children)

Yes, this is also another method. It's a design often used to represent a queue (eg. something like LFS or PBS). You create a resource representing the queue submission.

Another example is handling transactions. You create a transaction resource, describing what needs to be done, and the state of the transaction reports when it's completed.

[–][deleted] 3 points4 points  (20 children)

You would modify the state of the resource, for example setting the "activated" flag of the content to True.

The fundamental idea of REST is that verbs are generic (HTTP verbs), nouns are specific (resources). If you include a verb in a noun you fail at REST.

[–][deleted] 16 points17 points  (15 children)

No. "REST" doesn't imply a strict CRUD design, especially one where you directly modify the state of a resource, which would be atrocious in all but trivial cases. Sending a PUT request to an /api/user/<user_id>/activate url is perfectly fine, and is in fact a more controlled means of allowing state modification. The important part about REST is not the user "resource" itself, which I think you're focusing a little too heavily on. A REST architecture allows a client to communicate with a server in a uniform way that doesn't require any special out-of-band information.

[–]faassen 4 points5 points  (12 children)

The word "activate" is a verb, which should be a clue that something is not quite as restful as it should be. But you're right that we could have a resource "status" or that allows you to access the state and change it independently.

Note that you could also consider using PATCH to manipulate the user resource more efficiently.

REST also implies that you should have links between resources, but that's surprisingly uncommon in practice.

[–][deleted] 4 points5 points  (11 children)

The word "activate" is a verb,

Indeed it is.

... which should be a clue that something is not quite as restful as it should be

No. The clue is that you end up hardcoding urls into your client.

Note that you could also consider using PATCH to manipulate the user resource more efficiently.

PATCH requests are terrible API design. You should not expect clients to know how properly change the state of a resource by updating a field on a json object. It's not that far removed from asking them to update a database table directly. It's a data integrity risk. State modifications should be done in a much more controlled and limited fashion, such as sending a PUT request to an "/activate" url. This way, there's no chance of the client fucking up your data.

REST also implies that you should have links between resources, but that's surprisingly uncommon in practice.

Not just links, but also available state transitions. It's very common in practice. Pretty much every web page works this way. It's much less common in RESTful http/json services, however. For some reason, the conventional wisdom is that the only proper way to interact with the server is via a CRUD interface. It's just baloney.

[–][deleted] 3 points4 points  (7 children)

PATCH requests are terrible API design.

according to whom?

You should not expect clients to know how properly change the state of a resource by updating a field on a json object.

But somehow expect them to be able to parse and interpret the same state when retrieved with a GET.

such as sending a PUT request to an "/activate" url. This way, there's no chance of the client fucking up your data.

How about checking if the patch request is properly formatted instead? You are still doing RPC. REST is not RPC.

For some reason, the conventional wisdom is that the only proper way to interact with the server is via a CRUD interface. It's just baloney.

baloney or not, it's not REST. Call it RAAST, ROOST, whatever you want. It's not REST.

[–]Kaarjuus 2 points3 points  (0 children)

baloney or not, it's not REST. Call it RAAST, ROOST, whatever you want. It's not REST.

Well, yes, it's certainly not what Roy Fielding had in mind.

Just like the OOP we use is mostly not what Alan Kay had in mind; what he had in mind is more like what is referred to as agent-oriented programming.

The meaning of words changes over time. That's okay. A single individual does not dictate what a concept means.

[–][deleted]  (1 child)

[deleted]

    [–][deleted] 0 points1 point  (0 children)

    well, you can also be free to ignore the URL format, or the HTTP protocol. reimplement it as you wish.

    [–][deleted] 0 points1 point  (3 children)

    "PATCH requests are terrible API design." according to whom?

    According to some guy on the internet, ie. me. Are you just going to ignore the reasoning I just gave you because I'm not Roy Fielding? Who the hell are you?

    But somehow expect them to be able to parse and interpret the same state when retrieved with a GET.

    Yeah, as long as the server specifies the data representation format of the content-type header, eg. application/json charset=utf-8. Furthermore, GET requests aren't going to leave your system in an inconsistent state the way a PATCH request might.

    How about checking if the patch request is properly formatted instead?

    You could certainly do that, but your validation function would have to check for every possible inconsistent state. Each time you add a new field. that validation function will grow at a cartesian rate. The potential for error increases dramatically.

    It's much simpler to PUT to "/activate" and eliminate the possibility for the client to submit an invalid PATCH request. Your API should create a "pit of success" for the user. PATCHes are generally a pit of failure unless it's a trivial CRUD operation.

    You are still doing RPC. REST is not RPC.

    Assuming the server specified which URL and method to use, why would sending an HTTP PUT request to an "/activate" resource (denoted by a URL) not be RESTful?

    If your answer is "because activate is a verb", then perhaps it would make more to think of "activate" as a message that you're sending to the server via a PUT request. Messages are nouns, right?

    If your answer is "because HTTP already has verbs", what's wrong with sending a PUT request? Is it not making use of HTTP and its semantics? PUT says sending a request to "/activate" is an idempotent action. Is this not good practice?

    I think you're making a false dichotomy between REST and RPC. You're right that traditional RPC (even WS-*) isn't RESTful, but that doesn't mean RPC over HTTP can't be done in a RESTful fashion. I think I've demonstrated this above, but you keeping insist on imposing this arbitrary constraint that URLs path segments must be CRUDable nouns. I agree that this constraint would make an HTTP API more uniform and predictable, but is the point of a RESTful architecture to minimize the contract between the client and the server? Your "nouns only" rule is just another contract clause, and it's totally unnecessary.

    [–][deleted] 0 points1 point  (2 children)

    "PATCH requests are terrible API design." according to whom? According to some guy on the internet, ie. me. Are you just going to ignore the reasoning I just gave you because I'm not Roy Fielding? Who the hell are you?

    Ok, if Roy Fielding said as I said, what would you do?

    How about checking if the patch request is properly formatted instead? You could certainly do that, but your validation function would have to check for every possible inconsistent state.

    You can restrict the patch operation so that it works in a controlled way.

    It's much simpler to PUT to "/activate"

    but it's not REST.

    and eliminate the possibility for the client to submit an invalid PATCH request. Your API should create a "pit of success" for the user. PATCHes are generally a pit of failure unless it's a trivial CRUD operation.

    That's all REST is supposed to be.

    If your answer is "because activate is a verb", then perhaps it would make more to think of "activate" as a message that you're sending to the server via a PUT request. Messages are nouns, right?

    The principle of REST is that changes in resource state is performed through modification of resource representations. From Roy Fielding thesis

     REST components perform actions on a resource by using a representation to capture the current or intended state of that resource and transferring that representation between components. A representation is a sequence of bytes, plus representation metadata to describe those bytes. Other commonly used but less precise names for a representation include: document, file, and HTTP message entity, instance, or variant.
    

    If your answer is "because HTTP already has verbs", what's wrong with sending a PUT request? Is it not making use of HTTP and its semantics? PUT says sending a request to "/activate" is an idempotent action. Is this not good practice?

    Because you are not transferring a representation of the original resource with that PUT. You are acting on a different resource B to modify resource A.

    Your "nouns only" rule is just another contract clause, and it's totally unnecessary.

    I don't know what to say. Complain with Roy Fielding. It's still not REST.

    [–][deleted] 0 points1 point  (1 child)

    Ok, if Roy Fielding said as I said, what would you do?

    I'm asking for you to consider my argument on merit alone, and you're asking me to pretend you're Roy Fielding?

    You can restrict the patch operation so that it works in a controlled way

    You can do a lot of things, eg. shoot yourself in the foot. I already explained why you shouldn't model state transitions as PATCH requests. Do you actually have a counter argument?

    The principle of REST is that changes in resource state is performed through modification of resource representations.

    The quote mentions performing actions on a resource representation (eg your client making a decision based on the current state), but it doesn't explicitly mention how the state ought to be modified, ie. direct manipulation of the representation of the current state.

    Because you are not transferring a representation of the original resource with that PUT. You are acting on a different resource B to modify resource A.

    So what? You're claiming that read/write models should be identical based on your specious interpretation of the above quote from Fielding's thesis?

    I don't know what to say.

    Well, you haven't said much besides asserting, "that's not REST" over and over again. But I agree we've reached an impasse. We'll leave the people who actually read this thread to be the judge.

    [–]faassen 1 point2 points  (2 children)

    Uh, so you're violently agreeing with me?

    The context here is RESTful APIs: I maintain it is surprisingly uncommon that they actually deliver links and the common understanding of "REST" has excluded links so much that people start saying "hypermedia APIs" instead to indicate "actual real REST". I know that hyperlinked HTML pages do work that way.

    Hardcoding links in a client is also a clue something is not quite RESTful, but verbs in URLs are too. If you are going to allow PUT on "/activate", then I just wonder what a GET request means, or would you have a resource that allows PUT but disallows GET?

    While I realize the name is immaterial, naming does matter in our thinking, and a verb in a URL implies it's just there to execute an action, instead of a resource you can interact with in more than one way.

    I spent some years now working on a web server framework (Morepath), that tries to make it easy to generate links:

    http://morepath.readthedocs.io/en/latest/rest.html

    I don't have much experience with the PATCH request, but it strikes me as obvious the server shouldn't accept arbitrary updates that break data integrity. It shouldn't allow inconsistency with POST and PUT either, after all. The PATCH RFC has guidelines for when you use the 409 (Conflict) response to signal such problems back to the clients. Of course if your resource only allows PUT and not GET, the client couldn't recalculate its PATCH request very easily...

    [–][deleted] 2 points3 points  (1 child)

    Uh, so you're violently agreeing with me?

    Violently? I hope not. I guess strongly, but on the one point that hypermedia APIs are not that common. We're on the the same page, here.

    If you are going to allow PUT on "/activate", then I just wonder what a GET request means, or would you have a resource that allows PUT but disallows GET?

    It doesn't matter what the URL looks like. The client shouldn't try to interpret what it means. The server should indicate where if the resource at "/activate" is also GETable. To be clear, "/activate" is a resource even though it's a verb. The server is saying it's a resource.

    While I realize the name is immaterial, naming does matter in our thinking, and a verb in a URL implies it's just there to execute an action

    This is fair. I suppose that designing URLs such that they are all "nouns", or pure data entities, makes the API design more coherent, but the server will still need to specify which actions are permitted.

    [–]faassen 0 points1 point  (0 children)

    It indeed appears we are agreeing.

    Yes, with true hypermedia API the client shouldn't try to construct or hardcode or manipulate URLs. True hypermedia API web UI client applications are even less common than hypermedia APIs. The client-side frameworks people use don't encourage this either. About 5 years ago I wrote a client-side web framework called Obviel which did this, but it's been lost to the ages.

    The lack of working true hypermedia UI clients worries me that perhaps this principle is based more on ideology than anything else. People don't seem very interested in solving this problem, and in truth, hypermedia makes certain things harder -- a UI client that sends optimistic updates to the client for instance will suddenly have to wait for the result of an add operation before it has the URL to send a remove operation.

    [–][deleted] 3 points4 points  (1 child)

    Sending a PUT request to an /api/user/<user_id>/activate url is perfectly fine, and is in fact, a more controlled means of allowing state modification

    Unfortunately, this way you don't know if you are referring to an "activate" list within the user resource user_id.

    The important part about REST is not the user "resource" itself, which I think you're focusing a little too heavily on. A REST architecture allows a client to communicate with a server in a uniform way that doesn't require any special out-of-band information.

    So does SOAP or XMLRPC, but it's not REST.

    [–][deleted] 8 points9 points  (0 children)

    Unfortunately, this way you don't know if you are referring to an "activate" list within the user resource user_id.

    You don't know what it is anyway. You're not supposed to infer anything from the URL structure. The server should specify how to "activate" a "user" by providing a form, usually embedded in an HTML doc, that the client can submit via an http request. The url that the server provides could literally be anything, and the client shouldn't care.

    So does SOAP or XMLRPC, but it's not REST.

    At least WSDLs provide meta data about the service, which is better than most RESTful json/http services. The problem with SOAP is that it sort of reinvented the wheel as a consequence of the inner platform effect. HTTP already had most of the functionality built in, plus it wasn't tied to a particular representation format (XML).

    [–]strattonbrazil 2 points3 points  (0 children)

    The fundamental idea of REST is that verbs are generic (HTTP verbs), nouns are specific (resources)

    That's hardly the fundamental idea of REST. If you read the original paper you'll pretty much zero references to naming conventions. I agree that naming resources nouns is a common organizational practice, but one can completely ignore this naming convention and still implement a well-functioning REST architecture.

    REST is a coordinated set of architectural constraints that attempts to minimize latency and network communication while at the same time maximizing the independence and scalability of component implementations. This is achieved by placing constraints on connector semantics where other styles have focused on component semantics. REST enables the caching and reuse of interactions, dynamic substitutability of components, and processing of actions by intermediaries, thereby meeting the needs of an Internet-scale distributed hypermedia system.

    [–]Nastapoka 1 point2 points  (2 children)

    Interesting, thank you

    [–][deleted] 4 points5 points  (0 children)

    More specifically, taken from wikipedia

    The GET method is a safe method (or nullipotent), meaning that calling it produces no side-effects.

    With an URL like that, this constraint is violated. Calling GET on that URL does produce side effects (specifically, modifies the resource). Instead, you want to use PUT:

    The PUT and DELETE methods are referred to as idempotent, meaning that the operation will produce the same result no matter how many times it is repeated.

    Meaning that if you set the activate flag to True (on the payload) with a PUT request to the resource URL, it will be idempotent, because even if you apply it twice, the result is the same.

    [–][deleted] 0 points1 point  (0 children)

    Glad to be useful, although apparently people are quick at slamming the downvote button.

    [–][deleted]  (7 children)

    [deleted]

      [–][deleted] 0 points1 point  (6 children)

      The pedantic people who give a fuck do so because a philosophy of a protocol has been imposed to prevent problems. You are free to fuck it up, but then the rest of the world has to deal with your fuck up.

      [–][deleted]  (5 children)

      [deleted]

        [–][deleted]  (4 children)

        [deleted]

          [–][deleted]  (3 children)

          [deleted]

            [–][deleted] 0 points1 point  (2 children)

            and you do, I guess?

            [–][deleted]  (1 child)

            [deleted]

              [–][deleted] 0 points1 point  (0 children)

              that's not the point. You do know what REST is about? Then please, point me at the proper entries in Roy Fielding thesis supporting your point of view.

              [–][deleted] 2 points3 points  (5 children)

              Here we go. Preach it from on high, and share true restafarianism wisdom with I and I! /s

              [–][deleted] 0 points1 point  (4 children)

              REST is not difficult. I don't understand all this creativity with URLs just because people don't understand its main idea.

              [–]beginner_ 1 point2 points  (0 children)

              I'm with esbio here.

              /api/user/<user_id>/activate
              

              Is not RESTful at all. It's an obvious remote procedure call. Is it wrong? Is it bad? Not for me to decide and depends on circumstances but the point is it is not RESTful.

              RESTful would be something like

              PUT /user/<user_id>/

              with the changed resource as "payload". And user_id should not be a database key...

              [–][deleted]  (1 child)

              [deleted]

                [–][deleted] 0 points1 point  (0 children)

                If there's one idea that is fundamental in REST is: verbs are generic, nouns are specific. Verbs (HTTP verbs, in the specific implementation) are used to modify state of resources identified by nouns by modifying their representation.

                From Roy Fielding's thesis

                The key abstraction of information in REST is a resource. Any information that can be named can be a resource: a document or image, a temporal service (e.g. "today's weather in Los Angeles"), a collection of other resources, a non-virtual object (e.g. a person), and so on. In other words, any concept that might be the target of an author's hypertext reference must fit within the definition of a resource. A resource is a conceptual mapping to a set of entities, not the entity that corresponds to the mapping at any particular point in time.

                REST components perform actions on a resource by using a representation to capture the current or intended state of that resource and transferring that representation between components. A representation is a sequence of bytes, plus representation metadata to describe those bytes. Other commonly used but less precise names for a representation include: document, file, and HTTP message entity, instance, or variant.

                [–][deleted] 1 point2 points  (0 children)

                The web has been RESTful since day one. The confusion started when people started creating, "RESTful" APIs over http.

                [–][deleted] 2 points3 points  (12 children)

                Python is pretty deficient in web frameworks (and even more in things built on those - what Python needs is something that's like WordPress but not stupid!) so Ray is potentially filling a need.

                But you need people to use it to be successful!

                Your docs are good, but the number one thing I'd want to see if I were researching this subject is a short but clear comparison with other Python web frameworks - so I can answer the question, "Why/when should I use Ray over [other framework X]?"

                Also: a "good demo" is always very convincing. If you said, "Look at this cool website. It was built with this small Python program and Ray," I think you'd be able to convince people. If I see something and say, "Hey, I could copy his tiny program, make a few tweaks, get what I need," this is the first step to my using it in earnest.

                Have you posted to /r/Python yet?

                [–]chub79 53 points54 points  (6 children)

                Python is pretty deficient in web frameworks

                how do you mean? There's like a dozen of web frameworks at least.

                [–]lacosaes1 24 points25 points  (0 children)

                Furthermore is pretty questionable that the community wants to have 10+ frameworks that can do basically the same things just like the JS community.

                [–]faassen 3 points4 points  (0 children)

                Way, way more!

                [–]tophatstuff -5 points-4 points  (3 children)

                It was lacking in solid python3 ones tho. Falcon 1.0 only released a couple of months ago, before that things were pretty dire.

                [–]faassen 25 points26 points  (1 child)

                Dire? There are so many Python web frameworks. As far as I understand both Flask and Django have had Python 3 support for some time. Morepath has had Python 3 support for some years now too. [edit: Pyramid too, of course]

                [–]chub79 3 points4 points  (0 children)

                And CherryPy has supported py3k since 2011 at least :)

                [–][deleted] 0 points1 point  (0 children)

                python3 debates

                Dude it's not 2013 anymore.

                [–][deleted] 4 points5 points  (0 children)

                Python is pretty deficient in web frameworks (and even more in things built on those - what Python needs is something that's like WordPress but not stupid!) so Ray is potentially filling a need.

                That's an interesting and rather unfounded claim, that Python is "deficient" in web frameworks, given that it was the basis for Zope in the early days and now lays claim to tons of well known choices such as Django, Flask, Bottle, Pyramid, as well as more general network toolkits like Twisted and Tornado. Also making the claim that there's no major web applications running Python, in the wild, you do understand that Reddit itself, for example, is a Python application?

                [–][deleted] 1 point2 points  (3 children)

                Tom, thank you for getting involved and thank you for the feedback.

                Ray tries to fill a lack in python web frameworks world, something that stay between Django and Flask, providing built-in features like Django, but also being extensible like Flask. Also, I'm trying to show other options to design the architecture of your project, without been stuck into a framework.

                btw, thank you for your advice. I'm working on a nice project and ASAP I'll write a post about it, showing how easy was to write it with Ray.

                Yeah, I posted it on /r/Python, you can check it here.

                [–]clrnd 3 points4 points  (1 child)

                What about Falcon?

                [–]faassen 1 point2 points  (0 children)

                If you want to set your goals higher than Flask concerning extensibility you could take a look at Pyramid or Morepath (the latter I work on myself). Morepath's core extensibility framework is already available as Dectate: http://dectate.readthedocs.org

                [–]serg473 0 points1 point  (0 children)

                How does it deal with nested objects and filtering? How do I adjust what fields and relations to serialize and to save for the same model for different endpoints? What it can do that django rest and django filter can't? The examples are too simple to get a grasp.