WordPressParser asks WordPressClient to get blog-posts...
Is this really what a parser should do? Asking to get blog posts is not "parsing" by any definition of the term.
It's like scissors sending you an invitation to come over to your local barber shop. Now, scissors surely have their business in making it happen, but triggering this entire chain of events doesn't sound like something they should be in charge of.
For example, I need the media (photo and video) downloaded to disk. In
this case should I make 'download_media()' methods in the Parser
class, or is it better design to create a Downloader class?
I would create a separate class, because:
Downloading is a different responsibility than parsing - keep single responsibility principle in mind. It helps to keep track of which class does what as the project grows and allows to keep the code flexible - easy to change.
Different parsers may handle downloading in a similar, or even identical manner. By extracting this functionality into a separate class we can avoid code duplication, because the same Downloader implementation can be reused by different Parsers.
Should there be a class for BlogPosts? It seems to me that blog-posts
are objects (the equivalent to pages of a book, perhaps).
If they are nothing but strings - sheer text - it might not be necessary, but the cost of creating a BlogPost
class isn't all that high and at the very least it would make it explicit throughout your code that such and such variable represents a blog post and nothing else!
A good rule of thumb is to prefer domain specific types over primitive types. BlogPost
means something. A piece of text could be just anything. We are only humans and using domain specific types helps us to write bug-free code, because we let the type system guard us against committing type mismatch offenses (eg. confusing a blog post's url link with blog post's content).
Disclaimer: I don't know Python, I approach the question as a universal OOD question. If there is something Python-specific that escapes me here, I'd be happy if someone points it out.
In your latter scheme, you keep verbs in the URLs of your resources. This should be avoided as the HTTP verbs should be used for that purpose. Embrace the underlying protocol instead of ignoring, duplicating or overriding it.
Just look at DELETE /item/delete/:id
, you place the same information twice in the same request. This is superfluous and should be avoided. Personally, I'd be confused with this. Does the API actually support DELETE
requests? What if I place delete
in the URL and use a different HTTP verb instead? Will it match anything? If so, which one will be chosen? As a client of a properly designed API, I shouldn't have to ask such questions.
Maybe you need it to somehow support clients that cannot issue DELETE
or PUT
requests. If that's the case, I'd pass this information in an HTTP header. Some APIs use an X-HTTP-Method-Override
header for this specific purpose (which I think is quite ugly anyway). I certainly wouldn't place the verbs in the paths though.
Go for
GET /items # Read all items
GET /items/:id # Read one item
POST /items # Create a new item
PUT /items/:id # Update one item
DELETE /items/:id # Delete one item
What's important about the verbs is that they are already well-defined in the HTTP specification and staying in line with these rules allows you to use caches, proxies and possibly other tools external to your application that understand the semantics of HTTP but not your application semantics. Please note that the reason you should avoid having them in your URLs is not about RESTful APIs requiring readable URLs. It's about avoiding unnecessary ambiguity.
What's more, a RESTful API can map these verbs (or any subset thereof) to any set of application semantics, as long as it doesn't go against the HTTP specification. For example, it is perfectly possible to build a RESTful API that only uses GET requests if all operations that it allows are both safe and idempotent. The above mapping is just an example that fits your use case and is compliant with the spec. It doesn't necessarily have to be like this.
Please also mind that a truly RESTful API should never require a programmer to read extensive documentation of available URLs as long as you conform to the HATEOAS (Hypertext as the Engine of Application State) principle, which is one of the core assumptions of REST. The links can be utterly incomprehensible to humans as long as the client application can understand and use them to figure out possible application state transitions.
Best Answer
Yes. REST doesn't care what spelling you use for your identifiers.
One of the REST architecture constraints is the uniform interface; describing it in his thesis, Fielding wrote
There's nothing particularly magic about [GET, POST, PUT, DELETE, PATCH]. A very long time ago, that list would probably be [GET, HEAD, POST], because those were the only methods that had been standardized in RFC 1945. The others were documented with this warning:
The interoperability is key, in that it means that clients and servers and intermediary components that share an understanding of the message semantics can all cooperate together to produce a result -- without needing to understand the payload of the message.
Today, we have a method registry, with many different methods that you might want to use, including (as it happens) LOCK and UNLOCK. So, assuming your semantics agrees with those documented in the registry, you could use them.
In circumstances where you control both the client and the server, limiting yourself to the registered methods is less critical than it would be otherwise.
If you are targeting clients that understand code on demand, then you can give a generic client a link to download your client code to interact with your services.