Add RestListService and RestDetailService; update README.
This commit is contained in:
@@ -92,7 +92,7 @@ public:
|
||||
|
||||
bool GetBook(const std::string& id) {
|
||||
webcc::HttpResponse http_response;
|
||||
if (!Request(webcc::kHttpGet, "/books/" + id, "", &http_response)) {
|
||||
if (!Request(webcc::kHttpGet, "/book/" + id, "", &http_response)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ public:
|
||||
std::string book_json = Json::writeString(builder, root);
|
||||
|
||||
webcc::HttpResponse http_response;
|
||||
if (!Request(webcc::kHttpPost, "/books/" + id, book_json, &http_response)) {
|
||||
if (!Request(webcc::kHttpPost, "/book/" + id, book_json, &http_response)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ public:
|
||||
|
||||
bool DeleteBook(const std::string& id) {
|
||||
webcc::HttpResponse http_response;
|
||||
if (!Request(webcc::kHttpDelete, "/books/" + id, "", &http_response)) {
|
||||
if (!Request(webcc::kHttpDelete, "/book/" + id, "", &http_response)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -115,71 +115,77 @@ static bool BookFromJson(const std::string& json, Book* book) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BookListService::Handle(const std::string& http_method,
|
||||
const std::vector<std::string>& url_sub_matches,
|
||||
const webcc::UrlQuery& query,
|
||||
const std::string& request_content,
|
||||
std::string* response_content) {
|
||||
if (http_method == webcc::kHttpGet) {
|
||||
// Return all books as a JSON array.
|
||||
|
||||
Json::Value root(Json::arrayValue);
|
||||
for (const Book& book : g_book_store.books()) {
|
||||
root.append(book.ToJson());
|
||||
}
|
||||
|
||||
Json::StreamWriterBuilder builder;
|
||||
*response_content = Json::writeString(builder, root);
|
||||
|
||||
return true;
|
||||
// Return all books as a JSON array.
|
||||
// TODO: Support query parameters.
|
||||
bool BookListService::Get(const webcc::UrlQuery& /* query */,
|
||||
std::string* response_content) {
|
||||
Json::Value root(Json::arrayValue);
|
||||
for (const Book& book : g_book_store.books()) {
|
||||
root.append(book.ToJson());
|
||||
}
|
||||
|
||||
if (http_method == webcc::kHttpPost) {
|
||||
// Add a new book.
|
||||
Book book;
|
||||
if (BookFromJson(request_content, &book)) {
|
||||
return g_book_store.AddBook(book);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
Json::StreamWriterBuilder builder;
|
||||
*response_content = Json::writeString(builder, root);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Add a new book.
|
||||
// No response content.
|
||||
bool BookListService::Post(const std::string& request_content,
|
||||
std::string* /* response_content */) {
|
||||
Book book;
|
||||
if (BookFromJson(request_content, &book)) {
|
||||
return g_book_store.AddBook(book);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool BookDetailService::Handle(const std::string& http_method,
|
||||
const std::vector<std::string>& url_sub_matches,
|
||||
const webcc::UrlQuery& query,
|
||||
const std::string& request_content,
|
||||
std::string* response_content) {
|
||||
bool BookDetailService::Get(const std::vector<std::string>& url_sub_matches,
|
||||
std::string* response_content) {
|
||||
if (url_sub_matches.size() != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::string& book_id = url_sub_matches[0];
|
||||
|
||||
if (http_method == webcc::kHttpGet) {
|
||||
const Book& book = g_book_store.GetBook(book_id);
|
||||
if (!book.IsNull()) {
|
||||
Json::StreamWriterBuilder builder;
|
||||
*response_content = Json::writeString(builder, book.ToJson());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
} else if (http_method == webcc::kHttpPost) {
|
||||
// Update a book.
|
||||
Book book;
|
||||
if (BookFromJson(request_content, &book)) {
|
||||
book.id = book_id;
|
||||
return g_book_store.UpdateBook(book);
|
||||
}
|
||||
return false;
|
||||
|
||||
} else if (http_method == webcc::kHttpDelete) {
|
||||
return g_book_store.DeleteBook(book_id);
|
||||
const Book& book = g_book_store.GetBook(book_id);
|
||||
if (!book.IsNull()) {
|
||||
Json::StreamWriterBuilder builder;
|
||||
*response_content = Json::writeString(builder, book.ToJson());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Update a book partially.
|
||||
bool BookDetailService::Patch(const std::vector<std::string>& url_sub_matches,
|
||||
const std::string& request_content,
|
||||
std::string* response_content) {
|
||||
if (url_sub_matches.size() != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::string& book_id = url_sub_matches[0];
|
||||
|
||||
Book book;
|
||||
if (BookFromJson(request_content, &book)) {
|
||||
book.id = book_id;
|
||||
return g_book_store.UpdateBook(book);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BookDetailService::Delete(const std::vector<std::string>& url_sub_matches) {
|
||||
if (url_sub_matches.size() != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::string& book_id = url_sub_matches[0];
|
||||
|
||||
return g_book_store.DeleteBook(book_id);
|
||||
}
|
||||
|
||||
@@ -3,48 +3,42 @@
|
||||
|
||||
#include "webcc/rest_service.h"
|
||||
|
||||
// NOTE:
|
||||
// XxxListService and XxxDetailService are similar to the XxxListView
|
||||
// and XxxDetailView in Django (a Python web framework).
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// List Service handles the HTTP GET and returns the book list based on
|
||||
// BookListService handles the HTTP GET and returns the book list based on
|
||||
// query parameters specified in the URL.
|
||||
// The URL should be like:
|
||||
// - /books
|
||||
// - /books?name={BookName}
|
||||
// The query parameters could be regular expressions.
|
||||
class BookListService : public webcc::RestService {
|
||||
public:
|
||||
BookListService() = default;
|
||||
~BookListService() override = default;
|
||||
class BookListService : public webcc::RestListService {
|
||||
protected:
|
||||
// Return a list of books based on query parameters.
|
||||
// URL examples:
|
||||
// - /books
|
||||
// - /books?name={BookName}
|
||||
bool Get(const webcc::UrlQuery& query,
|
||||
std::string* response_content) final;
|
||||
|
||||
bool Handle(const std::string& http_method,
|
||||
const std::vector<std::string>& url_sub_matches,
|
||||
const webcc::UrlQuery& query,
|
||||
const std::string& request_content,
|
||||
std::string* response_content) override;
|
||||
// Create a new book.
|
||||
bool Post(const std::string& request_content,
|
||||
std::string* response_content) final;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Detail Service handles the following HTTP methods:
|
||||
// - GET
|
||||
// - PUT
|
||||
// - PATCH
|
||||
// - DELETE
|
||||
// The URL should be like: /books/{BookID}.
|
||||
class BookDetailService : public webcc::RestService {
|
||||
public:
|
||||
BookDetailService() = default;
|
||||
~BookDetailService() override = default;
|
||||
// The URL is like '/books/{BookID}', and the 'url_sub_matches' parameter
|
||||
// contains the matched book ID.
|
||||
class BookDetailService : public webcc::RestDetailService {
|
||||
protected:
|
||||
bool Get(const std::vector<std::string>& url_sub_matches,
|
||||
std::string* response_content) final;
|
||||
|
||||
bool Handle(const std::string& http_method,
|
||||
const std::vector<std::string>& url_sub_matches,
|
||||
const webcc::UrlQuery& query,
|
||||
const std::string& request_content,
|
||||
std::string* response_content) override;
|
||||
bool Patch(const std::vector<std::string>& url_sub_matches,
|
||||
const std::string& request_content,
|
||||
std::string* response_content) final;
|
||||
|
||||
bool Delete(const std::vector<std::string>& url_sub_matches) final;
|
||||
};
|
||||
|
||||
#endif // BOOK_SERVICE_H_
|
||||
|
||||
@@ -30,7 +30,7 @@ int main(int argc, char* argv[]) {
|
||||
"/books");
|
||||
|
||||
server.RegisterService(std::make_shared<BookDetailService>(),
|
||||
"/books/(\\d+)");
|
||||
"/book/(\\d+)");
|
||||
|
||||
server.Run();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user