diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index c6bf2d24..00000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1,3 +0,0 @@ -# These are supported funding model platforms - -github: oatpp diff --git a/README.md b/README.md index 6b89f0ef..19d20764 100644 --- a/README.md +++ b/README.md @@ -17,12 +17,10 @@ # Oat++ -**Attention** - -- Version `1.2.0` is now merged to Master and soon will receive a release tag. Get ready to migrate - see the [changelog](changelog/1.2.0.md) for details. - To get the best overview of `1.2.0` - checkout the new [example-crud](https://github.com/oatpp/example-crud) - CRUD + ORM + Swagger-UI. -- To checkout the latest `1.1.0` code use this commit - [e577681355ca652f317867c609e07cefabc37c0a](https://github.com/oatpp/oatpp/tree/e577681355ca652f317867c609e07cefabc37c0a) +**News** +- The new `1.2.0` version is now released. See [changelog](changelog/1.2.0.md) for details. +- Check out the new oatpp ORM - read more [here](https://oatpp.io/docs/components/orm/#declare-dbclient). --- @@ -31,245 +29,141 @@ It's fully loaded and contains all necessary components for effective production It's also light and has a small memory footprint. **Start** + - [Get Started](https://oatpp.io/docs/start/) - [Build For Unix/Linux](https://oatpp.io/docs/installation/unix-linux/) - [Build For Windows](https://oatpp.io/docs/installation/windows/) - [Examples](#examples) **About** + - [Website](https://oatpp.io/) - [Supported Platforms](https://oatpp.io/supported-platforms/) - Latest Benchmarks: [5 Million WebSockets](https://oatpp.io/benchmark/websocket/5-million/) - [Contributing to Oat++](CONTRIBUTING.md) **Join Our Community** -- Chat on **Gitter**. [Oat++ framework/Lobby](https://gitter.im/oatpp-framework/Lobby) -- Follow us on **Twitter** for latest news. [@oatpp_io](https://twitter.com/oatpp_io) -- Join community on **Reddit**. [r/oatpp](https://www.reddit.com/r/oatpp/) -## High Level Overview +- [Gitter](https://gitter.im/oatpp-framework/Lobby) - Talk to Oat++ developers and to other Oat++ users. +- [Twitter](https://twitter.com/oatpp_io) - Follow Oat++ on Twitter. +- [Reddit](https://www.reddit.com/r/oatpp/) - Follow Oat++ subreddit. +- [StackOverflow (new)](https://stackoverflow.com/questions/tagged/oat%2b%2b) - Post a Question. -- [API Controller And Request Mapping](#api-controller-and-request-mapping) - * [Declare Endpoint](#declare-endpoint) - * [Add CORS for Endpoint](#add-cors-for-endpoint) - * [Endpoint with Authorization](#endpoint-with-authorization) -- [Swagger-UI Annotations](#swagger-ui-annotations) - * [Additional Endpoint Info](#additional-endpoint-info) -- [API Client - Retrofit / Feign Like Client](#api-client---retrofit--feign-like-client) - * [Declare Client](#declare-client) - * [Using API Client](#using-api-client) -- [Object Mapping](#object-mapping) - * [Declare DTO](#declare-dto) - * [Serialize DTO Using ObjectMapper](#serialize-dto-using-objectmapper) +## Quick Overview +**Shortcuts:** -### API Controller And Request Mapping +- [Oat++ High Level Overview](https://oatpp.io/docs/start/high-level-overview/) - Get a quick overview of Oat++ features. +- [Example Project](https://github.com/oatpp/example-crud) - A complete example of a "CRUD" service (UserService) built with Oat++. REST + Swagger-UI + SQLite. -For more info see [Api Controller](https://oatpp.io/docs/components/api-controller/) +### Build Powerful API And Document It With Swagger-UI -#### Declare Endpoint +See [ApiController](https://oatpp.io/docs/components/api-controller/) for more details. ```cpp -ENDPOINT("PUT", "/users/{userId}", putUser, - PATH(Int64, userId), - BODY_DTO(Object, userDto)) -{ - userDto->id = userId; - return createDtoResponse(Status::CODE_200, m_database->updateUser(userDto)); -} -``` +ENDPOINT_INFO(getUserById) { + info->summary = "Get one User by userId"; -#### Add CORS for Endpoint - -For more info see [Api Controller / CORS](https://oatpp.io/docs/components/api-controller/#cors) - -```cpp -ADD_CORS(putUser) -ENDPOINT("PUT", "/users/{userId}", putUser, - PATH(Int64, userId), - BODY_DTO(Object, userDto)) -{ - userDto->id = userId; - return createDtoResponse(Status::CODE_200, m_database->updateUser(userDto)); -} -``` - -#### Endpoint with Authorization - -For more info see [Api Controller / Authorization](https://oatpp.io/docs/components/api-controller/#authorization-basic) - -```cpp -using namespace oatpp::web::server::handler; - -ENDPOINT("PUT", "/users/{userId}", putUser, - AUTHORIZATION(std::shared_ptr, authObject), - PATH(Int64, userId), - BODY_DTO(Object, userDto)) -{ - OATPP_ASSERT_HTTP(authObject->userId == "Ivan" && authObject->password == "admin", Status::CODE_401, "Unauthorized"); - userDto->id = userId; - return createDtoResponse(Status::CODE_200, m_database->updateUser(userDto)); -} -``` - -### Swagger-UI Annotations - -For more info see [Endpoint Annotation And API Documentation](https://oatpp.io/docs/components/api-controller/#endpoint-annotation-and-api-documentation) - -#### Additional Endpoint Info - -```cpp -ENDPOINT_INFO(putUser) { - // general - info->summary = "Update User by userId"; - info->addConsumes>("application/json"); info->addResponse>(Status::CODE_200, "application/json"); - info->addResponse(Status::CODE_404, "text/plain"); - // params specific + info->addResponse>(Status::CODE_404, "application/json"); + info->addResponse>(Status::CODE_500, "application/json"); + info->pathParams["userId"].description = "User Identifier"; } -ENDPOINT("PUT", "/users/{userId}", putUser, - PATH(Int64, userId), - BODY_DTO(Object, userDto)) +ENDPOINT("GET", "users/{userId}", getUserById, + PATH(Int32, userId)) { - userDto->id = userId; - return createDtoResponse(Status::CODE_200, m_database->updateUser(userDto)); + return createDtoResponse(Status::CODE_200, m_userService.getUserById(userId)); } -``` +``` -### API Client - Retrofit / Feign Like Client +### Access Databases And Keep Your Data Consistent -For more info see [Api Client](https://oatpp.io/docs/components/api-client/) - -#### Declare Client +See [Oat++ ORM](https://oatpp.io/docs/components/orm/) for more details. ```cpp -class UserService : public oatpp::web::client::ApiClient { -public: - - API_CLIENT_INIT(UserService) - - API_CALL("GET", "/users", getUsers) - API_CALL("GET", "/users/{userId}", getUserById, PATH(Int64, userId)) - -}; +QUERY(createUser, + "INSERT INTO users (username, email, role) VALUES (:username, :email, :role);", + PARAM(oatpp::String, username), + PARAM(oatpp::String, email), + PARAM(oatpp::Enum::AsString, role)) ``` -#### Using API Client +## Frequently Asked Questions -```cpp -auto response = userService->getUserById(id); -auto user = response->readBodyToDto>(objectMapper); -``` +### Q: "Oat++" name? -### Object Mapping +- "Oat" is something light, organic, and green. It can be easily cooked and consumed with no effort. +- "++" gives a hint that it is "something" for C++. -For more info see [Data Transfer Object (DTO)](https://oatpp.io/docs/components/dto/). +### Q: What is the main area of Oat++ application? -#### Declare DTO +Oat++ is used for many different purposes, from building REST APIs that run on embedded devices to +building microservices and highly-loaded cloud applications. -```cpp -class UserDto : public oatpp::DTO { +But the majority of use cases appears to be in **IoT** and **Robotics**. - DTO_INIT(UserDto, DTO) +### Q: How portable is Oat++? - DTO_FIELD(Int64, id); - DTO_FIELD(String, name); +Theoretically, Oat++ can be **easily** ported everywhere where you have **threads** and **network stack**. +With an additional comparably small effort, it can be ported almost everywhere depending on how +much you strip it and what would be the final binary size. -}; -``` +See [supported platforms](https://oatpp.io/supported-platforms/) for additional info. -#### Serialize DTO Using ObjectMapper +### Q: What is the size of a minimal Oat++ application? -```cpp -using namespace oatpp::parser::json::mapping; +About **1Mb**, depending on C/C++ std-lib and oatpp version. -auto user = UserDto::createShared(); -user->id = 1; -user->name = "Ivan"; +### Q: Which Oat++ API to choose, Simple or Async? -auto objectMapper = ObjectMapper::createShared(); -auto json = objectMapper->writeToString(user); -``` +Always choose **Simple API** wherever possible. Simple API is more developed and makes the code cleaner. -Output: +Async API is designed for small, specific tasks that run at high concurrency levels ex.: +- Serving file downloads to a large number of concurrent users (1K users and more). +- Streaming to a large number of clients (1K or more). +- Websocket Chat servers. -```json -{ - "id": 1, - "name": "Ivan" -} -``` +For all other purposes use simple API. -#### Serialize/Deserialize Data In Free Form +## Examples -While DTO objects apply strict rules on data ser/de, you can also -serialize/deserialize data in free form using type `oatpp::Any`. +### REST-API -```cpp -oatpp::Fields map = { - {"title", oatpp::String("Hello Any!")}, - {"listOfAny", - oatpp::List({ - oatpp::Int32(32), - oatpp::Float32(0.32), - oatpp::Boolean(true) - }) - } -}; +- [REST Service](https://github.com/oatpp/example-crud) - A complete example of a "CRUD" service (UserService) built with Oat++. REST + Swagger-UI + SQLite. +- [REST Client](https://github.com/oatpp/example-api-client) - Example project of how-to use Retrofit-like client wrapper (ApiClient) and how it works. -auto json = mapper->writeToString(map); -``` +### WebSocket -Output: - -```json -{ - "title": "Hello Any!", - "listOfAny": [ - 32, - 0.3199999928474426, - true - ] -} -``` - -### Examples: - -#### REST-API - -- [ApiClient-Demo](https://github.com/oatpp/example-api-client) - Example project of how-to use Retrofit-like client wrapper (ApiClient) and how it works. -- [AsyncApi](https://github.com/oatpp/example-async-api) - Example project of how-to use asynchronous API for handling large number of simultaneous connections. -- [CRUD](https://github.com/oatpp/example-crud) - Example project of how-to create basic CRUD endpoints. - -#### WebSocket - -- [Can-Chat](https://github.com/lganzzzo/canchat) - Feature-complete rooms-based chat for tens of thousands users. Client plus Server. +- [Can Chat](https://github.com/lganzzzo/canchat) - Feature-complete rooms-based chat for tens of thousands users. Client plus Server. - [WebSocket](https://github.com/oatpp/example-websocket) - Collection of oatpp WebSocket examples. -- [YUV-Websocket-Stream](https://github.com/oatpp/example-yuv-websocket-stream) - Example project how-to create a YUV image stream from a V4L device (i.E. Webcam) using websockets. +- [YUV Websocket Stream](https://github.com/oatpp/example-yuv-websocket-stream) - Example project how-to create a YUV image stream from a V4L device (i.E. Webcam) using websockets. +### Databases + +- [SQLite](https://github.com/oatpp/example-crud) - A complete example of a "CRUD" service. REST + Swagger-UI + SQLite. +- [PostgreSQL](https://github.com/oatpp/example-postgresql) - Example of a production-grade entity service storing information in PostgreSQL. With Swagger-UI and configuration profiles. +- [MongoDB](https://github.com/oatpp/example-mongodb) - Example project how to work with MongoDB using **oatpp-mongo** mondule. Project is a web-service with basic CRUD and Swagger-UI. + ### IoT - [Example-IoT-Hue](https://github.com/oatpp/example-iot-hue-ssdp) - Example project how-to create an Philips Hue compatible REST-API that is discovered and controllable by Hue compatible Smart-Home devices like Amazon Alexa or Google Echo. -#### Streaming +### Streaming -- [Media-Stream (Http-Live-Streaming)](https://github.com/oatpp/example-hls-media-stream) - Example project of how-to build HLS-streaming server using oat++ Async-API. -- [YUV-Websocket-Stream](https://github.com/oatpp/example-yuv-websocket-stream) - Example project how-to create a YUV image stream from a V4L device (i.E. Webcam) using websockets. +- [HTTP Live Streaming Server](https://github.com/oatpp/example-hls-media-stream) - Example project on how to build an HLS-streaming server using Oat++ asynchronous API. +- [YUV Websocket Stream](https://github.com/oatpp/example-yuv-websocket-stream) - Example project how-to create a YUV image stream from a V4L device (i.E. Webcam) using websockets. -#### TLS +### TLS -- [TLS-Libressl](https://github.com/oatpp/example-libressl) - Example project how-to setup secure connection and serve via HTTPS. +- [TLS With Libressl](https://github.com/oatpp/example-libressl) - Example project how-to setup secure connection and serve via HTTPS. -#### Microservices +### Microservices -- [Consul](https://github.com/oatpp/example-consul) - Example project of how-to use oatpp::consul::Client. Integration with Consul. +- [Consul Integration](https://github.com/oatpp/example-consul) - Example project on how to use [oatpp::consul::Client](https://oatpp.io/api/latest/oatpp-consul/rest/Client/). Consul integration. - [Microservices](https://github.com/oatpp/example-microservices) - Example project on how to build microservices with Oat++, and example on how to consolidate those microservices using [monolithization](https://oatpp.io/docs/monolithization/) technique. -#### Databases - -- [MongoDB](https://github.com/oatpp/example-mongodb) - Example project how to work with MongoDB using [oatpp-mongo](https://github.com/oatpp/oatpp-mongo) mondule. -Project is a web-service with basic CRUD and Swagger-UI. -- [PostgreSQL](https://github.com/oatpp/example-postgresql) - Example of a production grade entity service storing information in PostgreSQL. With Swagger-UI and configuration profiles. +### Asynchronous API +- [Async Service](https://github.com/oatpp/example-async-api) - Example project on how to use asynchronous API to handle a large number of simultaneous connections. diff --git a/changelog/1.2.0.md b/changelog/1.2.0.md index c7d8b8fa..d8632aa2 100644 --- a/changelog/1.2.0.md +++ b/changelog/1.2.0.md @@ -9,6 +9,7 @@ Contents: - [Object-Mapping - Type Interpretations](#type-interpretations) - [The new Oat++ ORM](#orm) - [Changes in oatpp::network Namespace](#changes-in-oatppnetwork-namespace) +- [New Modules](#new-modules) ## Continuous Multipart Streaming @@ -129,7 +130,7 @@ namespace __class { static oatpp::Type* getType(){ static Type type( - CLASS_ID, nullptr, nullptr, nullptr, nullptr, + CLASS_ID, nullptr, nullptr, { {"my-types", new Inter()} //<-- Add type interpretation } @@ -170,6 +171,11 @@ auto pointClone = mapper.readFromString(json); // Deserialize Point The main feature of the `1.2.0` release is the new ORM Framework. For details see - [Object-Relational Mapping (ORM) framework](https://oatpp.io/docs/components/orm/) +### ORM Adaptors + +- [oatpp-sqlite](https://github.com/oatpp/oatpp-sqlite) - SQLite adapter for Oat++ ORM. Full support. +- [oatpp-postgresql](https://github.com/oatpp/oatpp-postgresql) - Oat++ ORM adapter for PostgreSQL. Alpha version. + ## Changes in oatpp::network Namespace ### Moved and Renamed @@ -219,3 +225,10 @@ oatpp::network::tcp::client::ConnectionProvider::createShared( true /* use extended connections */ ); ``` + +## New Modules + +- [oatpp-sqlite](https://github.com/oatpp/oatpp-sqlite) - SQLite adapter for Oat++ ORM. Full support. +- [oatpp-postgresql](https://github.com/oatpp/oatpp-postgresql) - Oat++ ORM adapter for PostgreSQL. Alpha version. +- [oatpp-protobuf](https://github.com/oatpp/oatpp-protobuf) - Protobuf integration with oatpp object-mapping framework. Use +protobuf objects as regular oatpp DTOs. Serialize/Deserialize protobuf object to/from JSON, BSON and other oatpp supported formats.