All Projects → takezoe → Resty

takezoe / Resty

Licence: apache-2.0
Super easy REST API framework for Scala

Programming Languages

scala
5932 projects

Projects that are alternatives of or similar to Resty

Sample Spring Microservices
Many samples in different branches that shows how to create microservices with Spring Boot, Spring Cloud, Zipkin, Zuul, Eureka, Hystrix, Kubernetes, Elastic Stack and many more tools
Stars: ✭ 368 (+466.15%)
Mutual labels:  microservices, zipkin, hystrix
Nxplorerjs Microservice Starter
Node JS , Typescript , Express based reactive microservice starter project for REST and GraphQL APIs
Stars: ✭ 193 (+196.92%)
Mutual labels:  microservices, swagger, hystrix
Spring Petclinic Microservices
Distributed version of Spring Petclinic built with Spring Cloud
Stars: ✭ 814 (+1152.31%)
Mutual labels:  microservices, zipkin, hystrix
Micronaut Microservices Poc
Very simplified insurance sales system made in a microservices architecture using Micronaut
Stars: ✭ 394 (+506.15%)
Mutual labels:  microservices, zipkin
Oatpp
🌱Light and powerful C++ web framework for highly scalable and resource-efficient web application. It's zero-dependency and easy-portable.
Stars: ✭ 4,750 (+7207.69%)
Mutual labels:  microservices, webframework
Xxproject
SpringCloud 微服务综合实例。分布式配置中心,服务发现&负载均衡,链路断路器,API网关,OAuth2认证授权,分布式追踪,ELK日志中心,Ansible/Docker持续交付等最佳实践。
Stars: ✭ 371 (+470.77%)
Mutual labels:  zipkin, hystrix
Sanic Ms
基于sanic的微服务基础架构
Stars: ✭ 336 (+416.92%)
Mutual labels:  swagger, zipkin
Swagger Stats
API Observability. Trace API calls and Monitor API performance, health and usage statistics in Node.js Microservices.
Stars: ✭ 559 (+760%)
Mutual labels:  microservices, swagger
Spring Samples For All
spring、spring-boot、spring-cloud 常用整合用例
Stars: ✭ 401 (+516.92%)
Mutual labels:  zipkin, hystrix
Phpboot
☕️ 🚀 tiny & fast PHP framework for building Microservices/RESTful APIs, with useful features: IOC, Hook, ORM, RPC, Swagger, Annotation, Parameters binding, Validation, etc.
Stars: ✭ 638 (+881.54%)
Mutual labels:  microservices, swagger
Spring Cloud Netflix Example
spring-cloud-netflix-example is an example for microservices system
Stars: ✭ 760 (+1069.23%)
Mutual labels:  swagger, zipkin
Springcloud
基于SpringCloud2.1的微服务开发脚手架,整合了spring-security-oauth2、nacos、feign、sentinel、springcloud-gateway等。服务治理方面引入elasticsearch、skywalking、springboot-admin、zipkin等,让项目开发快速进入业务开发,而不需过多时间花费在架构搭建上。持续更新中
Stars: ✭ 6,997 (+10664.62%)
Mutual labels:  zipkin, hystrix
Springcloud Learning
Spring Cloud基础教程,持续连载更新中
Stars: ✭ 6,839 (+10421.54%)
Mutual labels:  zipkin, hystrix
Connexion
Swagger/OpenAPI First framework for Python on top of Flask with automatic endpoint validation & OAuth2 support
Stars: ✭ 3,869 (+5852.31%)
Mutual labels:  microservices, swagger
Spring Cloud Microservice Examples
spring-cloud-microservice-examples
Stars: ✭ 372 (+472.31%)
Mutual labels:  zipkin, hystrix
Superboot
随着技术日新月异,新技术新平台不断出现,对现如今的开发人员来说选择快速高效的框架进行项目开发,既能提高产出,又能节约时间。本框架无需开发即可实现服务注册、服务发现、负载均衡、服务网关、配置中心、API管理、分布式事务、支撑平台、集成框架、数据传输加密等功能,是学习SpringCloud整体业务模式的完整示例,并且可以直接用于生产环境
Stars: ✭ 341 (+424.62%)
Mutual labels:  swagger, hystrix
Goa
Design-based APIs and microservices in Go
Stars: ✭ 4,493 (+6812.31%)
Mutual labels:  microservices, swagger
Surging
Surging is a micro-service engine that provides a lightweight, high-performance, modular RPC request pipeline. The service engine supports http, TCP, WS,Grpc, Thrift,Mqtt, UDP, and DNS protocols. It uses ZooKeeper and Consul as a registry, and integrates it. Hash, random, polling, Fair Polling as a load balancing algorithm, built-in service gove…
Stars: ✭ 3,088 (+4650.77%)
Mutual labels:  microservices, swagger
Java Spring Cloud
Distributed tracing for Spring Boot, Cloud and other Spring projects
Stars: ✭ 326 (+401.54%)
Mutual labels:  microservices, hystrix
Simplemall
基于SpringCloud的微服务架构实战案例项目,以一个简单的购物流程为示例,融合spring cloud 相关组件,如spring-cloud-netflix、swagger等
Stars: ✭ 687 (+956.92%)
Mutual labels:  swagger, hystrix

Resty Build Status Maven Central License

Super easy REST API framework for Scala

You can run the sample project by hitting following commands:

$ git clone https://github.com/takezoe/resty-sample.git
$ cd resty-sample/
$ sbt ~jetty:start

Check APIs via Swagger UI at: http://localhost:8080/swagger-ui/.

Getting started

This is a simplest controller example:

import com.github.takezoe.resty._

class HelloController {
  @Action(method = "GET", path = "/hello/{name}")
  def hello(name: String): Message = {
    Message(s"Hello ${name}!")
  }
}

case class Message(message: String)

Define a web listener that registers your controller.

@WebListener
class InitializeListener extends ServletContextListener {
  override def contextDestroyed(sce: ServletContextEvent): Unit = {
  }
  override def contextInitialized(sce: ServletContextEvent): Unit = {
    Resty.register(new HelloController())
  }
}

Let's test this controller.

$ curl -XGET http://localhost:8080/hello/resty
{"message": "Hello resty!" }

Annotations

Resty provides some annotations including @Action.

@Controller

You can add @Controller to the controller class to define the controller name and description. They are applied to Swagger JSON.

parameter required description
name optional name of the controller
description optional description of the controller
@Controller(name = "hello", description = "HelloWorld API")
class HelloController {
  ...
}

@Action

We already looked @Action to annotate the action method. It has some more parameters to add more information about the action.

parameter required description
method required GET, POST, PUT or DELETE
path required path of the action ({name} defines path parameter)
description optional description of the method
deprecated optional if true then deprecated (default is false)
class HelloController {
  @Action(method = "GET", path = "/v1/hello", 
    description = "Old version of HelloWorld API", deprecated = true)
  def hello() = {
    ...
  }
}

@Param

@Param is added to the arguments of the action method to define advanced parameter binding.

parameter required description
from optional query, path, header or body
name optional parameter or header name (default is arg name)
description optional description of the parameter
class HelloController {
  @Action(method = "GET", path = "/hello")
  def hello(
    @Param(from = "query", name = "user-name") userName: String,
    @Param(from = "header", name = "User-Agent") userAgent: String
  ) = {
    ...
  }
}

Types

Resty supports following types as the parameter argument:

  • Unit
  • String
  • Int
  • Long
  • Boolean
  • Option[T]
  • Seq[T]
  • Array[T]
  • Array[Byte] (for Base64 encoded string)
  • AnyRef (for JSON in the request body)

Also following types are supported as the return value of the action method:

  • String is responded as text/plain; charset=UTF-8
  • Array[Byte], InputStream, java.io.File are responded as application/octet-stream
  • AnyRef is responded as application/json
  • ActionResult[_] is responded as specified status, headers and body
  • Future[_] is processed asynchronously using AsyncContext

Servlet API

You can access Servlet API by defining method arguments with following types:

  • HttpServletRequest
  • HttpServletResponse
  • HttpSession
  • ServletContext
class HelloController {
  @Action(method = "GET", path = "/hello")
  def hello(request: HttpServletRequest): Message = {
    val name = request.getParameter("name")
    Message(s"Hello ${name}!")
  }
}

Validation

It's possible to validate JSON properties by asserting properties in the constructor of the mapped case class.

case class Message(message: String){
  assert(message.length < 10, "message must be less than 10 charactors.")
}

When the parameter value is invalid, Resty responds the following response with the 400 BadRequest status:

{
  "errors": [
    "message must be less than 10 charactors."
  ]
}

HTTP client

HttpClientSupport trait offers methods to send HTTP request. You can call other Web APIs easily using these methods.

class HelloController extends HttpClientSupport {
  @Action(method = "GET", path = "/hello/{id}")
  def hello(id: Int): Message = {
    // Call other API using methods provided by HttpClientSupport
    val user: User = httpGet[User](s"http://localhost:8080/user/${id}")
    Message(s"Hello ${user.name}!")
  }
  
  @Action(method = "GET", path = "/hello-async/{id}")
  def helloAsync(id: Int): Future[Message] = {
    // HttpClientSupport also supports asynchronous communication
    val future: Future[Either[ErrorModel, User]] = httpGetAsync[User](s"http://localhost:8080/user/${id}")
    future.map {
      case Right(user) => Message(s"Hello ${user.name}!")
      case Left(error) => throw new ActionResultException(InternalServerError(error))
    }
  }
}

These methods have retrying ability and circuit breaker. You can configure these behavior by defining HttpClientConfig as an implicit value.

class HelloController extends HttpClientSupport {

  implicit override val httpClientConfig = HttpClientConfig(
    maxRetry      = 5,     // max number of retry. default is 0 (no retry)
    retryInterval = 500,   // interval of retry (msec). default is 0 (retry immediately)
    maxFailure    = 3,     // max number until open circuit breaker. default is 0 (disabling circuit breaker)
    resetInterval = 60000  // interval to reset closed circuit breaker (msec). default is 60000
  )
  
  ...
}

Swagger integration

Resty provides Swagger integration in default. Swagger JSON is provided at http://localhost:8080/swagger.json and also Swagger UI is available at http://localhost:8080/swagger-ui/.

Swagger integration

Add following parameter to web.xml to enable Swagger integration:

<context-param>
  <param-name>resty.swagger</param-name>
  <param-value>enable</param-value>
</context-param>

By enabling runtime-scaladoc-reader plugin in your project, Scaladoc of controller classes is reflected to Swagger JSON. For example, Scaladoc of the controller class is used as the tag description, and Scaladoc of the method is used as the operation description, the parameter description and the response description.

addCompilerPlugin("com.github.takezoe" %% "runtime-scaladoc-reader" % "1.0.1")

Hystrix integration

Resty also provides Hystrix integration in default. Metrics are published for each operations. The stream endpoint is available at http://localhost:8080/hystrix.stream. Register this endpoint to the Hystrix dashboard.

Hystrix integration

Add following parameter to web.xml to enable Hystrix integration:

<context-param>
  <param-name>resty.hystrix</param-name>
  <param-value>enable</param-value>
</context-param>

Zipkin integration

Furthermore, Resty supports Zipkin as well. You can send execution results to the Zipkin server by enabling Zipkin support and using HttpClientSupport for calling other APIs.

Add following parameters to web.xml to enable Zipkin integration:

<context-param>
  <param-name>resty.zipkin</param-name>
  <param-value>enable</param-value>
</context-param>
<context-param>
  <param-name>resty.zipkin.service.name</param-name>
  <param-value>resty-sample</param-value>
</context-param>
<context-param>
  <param-name>resty.zipkin.sample.rate</param-name>
  <param-value>1.0</param-value>
</context-param>
<context-param>
  <param-name>resty.zipkin.server.url</param-name>
  <param-value>http://127.0.0.1:9411/api/v1/spans</param-value>
</context-param>

WebJars support

WebJars is a cool stuff to integrate frontend libraries with JVM based applications. Resty can host static files that provided by WebJars for frontend applications.

Add a following parameter to web.xml to enable WebJars hosting:

<context-param>
  <param-name>resty.wabjars</param-name>
  <param-value>enable</param-value>
</context-param>
<context-param>
  <param-name>resty.wabjars.path</param-name>
  <param-value>/public/assets/*</param-value>
</context-param>

You can add WebJars dependencies in your application as following:

libraryDependencies += "org.webjars" %  "jquery" % "3.1.1-1"

Then import JavaScript library as following:

<script src="/public/assets/jquery.min.js" type='text/javascript'></script>

Static files hosting

Resty is including some base servlets to host static files. You can provide a frontend application through Resty application from the classpath or the file system by defining following servlet based on these classes.

// Host static files on the file system
@WebServlet(name="FileResourceServlet", urlPatterns=Array("/public/*"))
class MyFileResourceServlet extends FileResourceServlet("src/main/webapp")

// Host static files in the classpath
@WebServlet(name="ClasspathResourceServlet", urlPatterns=Array("/public/*"))
class MyClasspathResourceServlet extends ResourceServlet("com/github/resty/sample/public")

CORS support

CORS support can be enabled by adding following parameters to web.xml:

<context-param>
  <param-name>resty.cors</param-name>
  <param-value>enable</param-value>
</context-param>
<context-param>
  <param-name>resty.cors.allowedOrigins</param-name>
  <param-value>http://localhost:8080</param-value>
</context-param>
<context-param>
  <param-name>resty.cors.allowedMethods</param-name>
  <param-value>GET, POST</param-value>
</context-param>
<context-param>
  <param-name>resty.cors.allowedHeaders</param-name>
  <param-value>Content-Type</param-value>
</context-param>
<context-param>
  <param-name>resty.cors.allowCredentials</param-name>
  <param-value>true</param-value>
</context-param>
<context-param>
  <param-name>resty.cors.preflightMaxAge</param-name>
  <param-value>1800</param-value>
</context-param>

Description about optional parameters:

  • resty.cors.allowedOrigins: Comma separated list of hosts and ports which will be allowed to make cross-origin requests (default is *).
  • resty.cors.allowedMethods: Comma separated list of HTTP methods will be allowed (default is GET, POST, PUT, DELETE).
  • resty.cors.allowedHeaders: Comma separated list of allowed HTTP headers (most headers are allowed in default).
  • resty.cors.allowCredentials: Set this parameter to true to allow cookies in CORS requests (default is false).
  • resty.cors.preflightMaxAge: Number of seconds that preflight request can be cached in the client (default is 0).
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].