Skip to content

Commit

Permalink
#78 Added support for HTTP PATCH method, updated CRUD example
Browse files Browse the repository at this point in the history
  • Loading branch information
loentar committed Jan 24, 2022
1 parent ef1f907 commit 75801cd
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 38 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
tmp
*.creator.user*
*.creator.user*
CMakeLists.txt.user
2 changes: 2 additions & 0 deletions core/common/src/HttpMessage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ void HttpRequest::setMethod(const char* method)
this->method = HttpMethod::PUT;
} else if (!strcmp(method, "DELETE")) {
this->method = HttpMethod::DELETE;
} else if (!strcmp(method, "PATCH")) {
this->method = HttpMethod::PATCH;
} else {
this->method = HttpMethod::UNKNOWN;
}
Expand Down
3 changes: 2 additions & 1 deletion core/common/src/HttpMethod.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ enum class HttpMethod
POST,
GET,
PUT,
DELETE
DELETE,
PATCH
};

} // namespace ngrest
Expand Down
67 changes: 46 additions & 21 deletions examples/crud/src/Crud.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,37 +37,56 @@ class Db
return instance;
}

std::vector<int> getIds()
std::vector<User> getIds()
{
// "select id from storage;"
std::vector<int> res;
for (const auto& item : storage)
res.push_back(item.first);
// "select * from storage;"
std::vector<User> res;
for (const auto& item : storage) {
res.push_back(item.second);
}
return res;
}

void create(int id, const std::string& data)
int create(User user)
{
// "insert into storage(id, data) values (:id, :data);"
auto it = storage.find(id);
// "insert into storage(id, user) values (:id, :user);"
user.id = nextUserId;
auto it = storage.find(nextUserId);
NGREST_ASSERT_HTTP(it == storage.end(), HTTP_STATUS_409_CONFLICT, "Item already exist");
storage.insert({id, data});
storage.insert({nextUserId, user});

++nextUserId;
return user.id;
}

std::string get(int id)
User get(int id)
{
// "select data from storage where id = :id;"
// "select user from storage where id = :id;"
auto it = storage.find(id);
NGREST_ASSERT_HTTP(it != storage.end(), HTTP_STATUS_404_NOT_FOUND, "Item not found");
return it->second;
}

void update(int id, const std::string& data)
void update(int id, User user)
{
// "update storage set user = :user where id = :id;"
auto it = storage.find(id);
NGREST_ASSERT_HTTP(it != storage.end(), HTTP_STATUS_404_NOT_FOUND, "Item not found");
user.id = id;
it->second = user;
}

void patch(int id, const UserPatch& user)
{
// "update storage set data = :data where id = :id;"
// "update storage set user = :user where id = :id;"
auto it = storage.find(id);
NGREST_ASSERT_HTTP(it != storage.end(), HTTP_STATUS_404_NOT_FOUND, "Item not found");
it->second = data;
if (user.name.isValid()) {
it->second.name = *user.name;
}
if (user.email.isValid()) {
it->second.email = *user.email;
}
}

void del(int id)
Expand All @@ -79,28 +98,34 @@ class Db
}

private:
std::unordered_map<int, std::string> storage;
std::unordered_map<int, User> storage;
int nextUserId = 1;
};


std::vector<int> Crud::getIds()
std::vector<User> Crud::getAll()
{
return Db::inst().getIds();
}

void Crud::create(int id, const std::string& data)
int Crud::create(const User& user)
{
Db::inst().create(id, data);
return Db::inst().create(user);
}

std::string Crud::read(int id) const
User Crud::get(int id) const
{
return Db::inst().get(id);
}

void Crud::update(int id, const std::string& data)
void Crud::update(int id, const User &user)
{
Db::inst().update(id, user);
}

void Crud::patch(int id, const UserPatch &user)
{
Db::inst().update(id, data);
Db::inst().patch(id, user);
}

void Crud::del(int id)
Expand Down
75 changes: 60 additions & 15 deletions examples/crud/src/Crud.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,63 +24,108 @@
#include <string>
#include <vector>
#include <ngrest/common/Service.h>
#include <ngrest/common/Nullable.h>

namespace ngrest {
namespace examples {

/**
* @brief User user
*/
struct User
{
ngrest::Nullable<int> id; //!< user id
std::string name; //!< user name
std::string email; //!< user email
};


/**
* @brief User user for PATCH request
*/
struct UserPatch
{
ngrest::Nullable<std::string> name; //!< user name, don't update if not set
ngrest::Nullable<std::string> email; //!< user email, don't update if not set
};


//! Example on how to use a service in CRUD model
// *location: ngrest/examples/data
// *location: ngrest/examples/users
class Crud: public Service
{
public:
//! get all identifiers from resource
/*!
example of request:
http://server:port/ngrest/examples/data/
GET http://server:port/ngrest/examples/users/
*/
// *method: GET
// *location: /
std::vector<int> getIds();
std::vector<User> getAll();

//! create new object in resource
/*!
example of request:
http://server:port/ngrest/examples/data/1
POST http://server:port/ngrest/examples/users/create
-- body -----------------------
{
"data": "Object #1"
"name": "John Doe",
"email": "[email protected]"
}
-------------------------------
returns id of created user:
-- response -------------------
{
"result": 1
}
-------------------------------
*/
// *method: POST
// *location: /{id}
void create(int id, const std::string& data);
// *location: /create
int create(const User& user);

//! create get object by identifier
/*!
example of request:
http://server:port/ngrest/examples/data/1
http://server:port/ngrest/examples/users/1
*/
// *method: GET
// *location: /{id}
std::string read(int id) const;
User get(int id) const;

//! update existing object in resource
//! update whole user record
/*!
example of request:
http://server:port/ngrest/examples/data/1
PUT http://server:port/ngrest/examples/users/1
-- body -----------------------
{
"data": "Updated object #1"
"name": "James Doe",
"email": "[email protected]"
}
*/
// *method: PUT
// *location: /{id}
void update(int id, const std::string& data);
void update(int id, const User& user);

//! update particular fields of specified user
/*!
example of request:
PATCH http://server:port/ngrest/examples/users/1
-- body -----------------------
{
"name": "Jimm Doe"
}
*/
// *method: PATCH
// *location: /{id}
void patch(int id, const UserPatch& user);

//! delete existing object by identifier
//! delete existing user by identifier
/*!
example of request:
http://server:port/ngrest/examples/data/1
DELETE http://server:port/ngrest/examples/users/1
*/
// *method: DELETE
// *location: /{id}
Expand Down

0 comments on commit 75801cd

Please sign in to comment.