{"action":"created","comment":{"url":"https://api.github.com/repos/line/armeria/pulls/comments/169244966","pull_request_review_id":97732498,"id":169244966,"diff_hunk":"@@ -0,0 +1,718 @@\n+.. _@ConsumeType: apidocs/index.html?com/linecorp/armeria/server/annotation/ConsumeType.html\n+.. _@Decorator: apidocs/index.html?com/linecorp/armeria/server/annotation/Decorator.html\n+.. _@Default: apidocs/index.html?com/linecorp/armeria/server/annotation/Default.html\n+.. _@Delete: apidocs/index.html?com/linecorp/armeria/server/annotation/Delete.html\n+.. _@ExceptionHandler: apidocs/index.html?com/linecorp/armeria/server/annotation/ExceptionHandler.html\n+.. _@Get: apidocs/index.html?com/linecorp/armeria/server/annotation/Get.html\n+.. _@Head: apidocs/index.html?com/linecorp/armeria/server/annotation/Head.html\n+.. _@Header: apidocs/index.html?com/linecorp/armeria/server/annotation/Header.html\n+.. _@Options: apidocs/index.html?com/linecorp/armeria/server/annotation/Options.html\n+.. _@Order: apidocs/index.html?com/linecorp/armeria/server/annotation/Order.html\n+.. _@Param: apidocs/index.html?com/linecorp/armeria/server/annotation/Param.html\n+.. _@Patch: apidocs/index.html?com/linecorp/armeria/server/annotation/Patch.html\n+.. _@Path: apidocs/index.html?com/linecorp/armeria/server/annotation/Path.html\n+.. _@Post: apidocs/index.html?com/linecorp/armeria/server/annotation/Post.html\n+.. _@ProduceType: apidocs/index.html?com/linecorp/armeria/server/annotation/ProduceType.html\n+.. _@Put: apidocs/index.html?com/linecorp/armeria/server/annotation/Put.html\n+.. _@RequestConverter: apidocs/index.html?com/linecorp/armeria/server/annotation/RequestConverter.html\n+.. _@RequestObject: apidocs/index.html?com/linecorp/armeria/server/annotation/RequestObject.html\n+.. _@ResponseConverter: apidocs/index.html?com/linecorp/armeria/server/annotation/ResponseConverter.html\n+.. _@Trace: apidocs/index.html?com/linecorp/armeria/server/annotation/Trace.html\n+.. _AggregatedHttpMessage: apidocs/index.html?com/linecorp/armeria/common/AggregatedHttpMessage.html\n+.. _ByteArrayRequestConverterFunction: apidocs/index.html?com/linecorp/armeria/server/annotation/ByteArrayRequestConverterFunction.html\n+.. _DecoratingServiceFunction: apidocs/index.html?com/linecorp/armeria/server/DecoratingServiceFunction.html\n+.. _ExceptionHandlerFunction: apidocs/index.html?com/linecorp/armeria/server/annotation/ExceptionHandlerFunction.html\n+.. _HttpParameters: apidocs/index.html?com/linecorp/armeria/common/HttpParameters.html\n+.. _HttpRequest: apidocs/index.html?com/linecorp/armeria/common/HttpRequest.html\n+.. _HttpResponse: apidocs/index.html?com/linecorp/armeria/common/HttpResponse.html\n+.. _HttpResponseException: apidocs/index.html?com/linecorp/armeria/server/HttpResponseException.html\n+.. _HttpStatusException: apidocs/index.html?com/linecorp/armeria/server/HttpStatusException.html\n+.. _JacksonRequestConverterFunction: apidocs/index.html?com/linecorp/armeria/server/annotation/JacksonRequestConverterFunction.html\n+.. _PathMapping: apidocs/index.html?com/linecorp/armeria/server/PathMapping.html\n+.. _Request: apidocs/index.html?com/linecorp/armeria/common/Request.html\n+.. _RequestContext: apidocs/index.html?com/linecorp/armeria/common/RequestContext.html\n+.. _RequestConverterFunction: apidocs/index.html?com/linecorp/armeria/server/annotation/RequestConverterFunction.html\n+.. _ResponseConverterFunction: apidocs/index.html?com/linecorp/armeria/server/annotation/ResponseConverterFunction.html\n+.. _ServerBuilder: apidocs/index.html?com/linecorp/armeria/server/ServerBuilder.html\n+.. _Service: apidocs/index.html?com/linecorp/armeria/server/Service.html\n+.. _ServiceRequestContext: apidocs/index.html?com/linecorp/armeria/server/ServiceRequestContext.html\n+.. _StringRequestConverterFunction: apidocs/index.html?com/linecorp/armeria/server/annotation/StringRequestConverterFunction.html\n+\n+.. _server-annotated-service:\n+\n+Annotated HTTP Service\n+======================\n+\n+Armeria provides a way to write an HTTP service using annotations. It helps a user make his or her code\n+simple and easy to understand. A user is able to run an HTTP service by fewer lines of code using\n+annotations as follows. ``getHello()`` method in the example would be mapped to the path of ``/hello``\n+with an HTTP GET method.\n+\n+.. code-block:: java\n+\n+    ServerBuilder sb = new ServerBuilder();\n+    sb.annotatedService(new Object() {\n+        @Get(\"/hello/{name}\")\n+        public HttpResponse hello(@Param(\"name\") String name) {\n+            return HttpResponse.of(HttpStatus.OK,\n+                                   MediaType.PLAIN_TEXT_UTF_8,\n+                                   \"Hello, %s!\", name);\n+        }\n+    });\n+\n+Mapping HTTP service methods\n+----------------------------\n+\n+To map a Java method in an annotated HTTP service class to HTTP path, it has to be annotated with one of\n+HTTP method annotations. Here is the list of HTTP method annotations that Armeria supports. Each of them\n+is mapped to the HTTP method which has the same name.\n+\n+- `@Get`_\n+- `@Head`_\n+- `@Post`_\n+- `@Put`_\n+- `@Delete`_\n+- `@Options`_\n+- `@Patch`_\n+- `@Trace`_\n+\n+To handle a single HTTP method in a single service method, you can annotate your service method simply,\n+as follows.\n+\n+.. code-block:: java\n+\n+    class MyAnnotatedServiceClass {\n+\n+        @Get(\"/hello\")\n+        public HttpResponse hello() { ... }\n+    }\n+\n+There are 5 PathMapping_ types provided for describing a path.\n+\n+- Exact mapping, e.g. ``/hello`` or ``exact:/hello``\n+\n+  - a service method will handle the path exactly matched with the specified path.\n+\n+- Mapping with path prefix, e.g. ``prefix:/hello``\n+\n+  - a service method will handle every path which starts with the specified prefix.\n+\n+- Mapping with path variables, e.g ``/hello/{name}`` or ``/hello/:name``\n+\n+  - a service method will handle the path matched with the specified path pattern. A path variable in the\n+    specified pattern may be mapped to a parameter of the service method.\n+\n+- Mapping with regular expression, e.g. ``regex:^/hello/(?<name>.*)$``\n+\n+  - a service method will handle the path matched with the specified regular expression. If a named capturing\n+    group exists in the regular expression, it may be mapped to a parameter of the service method.\n+\n+- Mapping with glob pattern, e.g. ``glob:/*/hello/**``\n+\n+  - a service method will handle the path matched with the specified glob pattern. A wildcard is mapped to\n+    an index which starts with ``0``, so it may be mapped to a parameter of the service method.\n+\n+You can get the value of a path variable, a named capturing group of the regular expression or wildcards of\n+the glob pattern in your service method by annotating a parameter with `@Param`_ as follows.\n+Please refer to :ref:`parameter-injection` for more information about `@Param`_.\n+\n+.. code-block:: java\n+\n+    class MyAnnotatedServiceClass {\n+\n+        @Get(\"/hello/{name}\")\n+        public HttpResponse pathvar(@Param(\"name\") String name) { ... }\n+\n+        @Get(\"regex:^/hello/(?<name>.*)$\")\n+        public HttpResponse regex(@Param(\"name\") String name) { ... }\n+\n+        @Get(\"glob:/*/hello/**\")\n+        public HttpResponse glob(@Param(\"0\") String prefix, @Param(\"1\") String name) { ... }\n+    }\n+\n+There are Java methods which are mapped to one HTTP method in the example above. What should you do if you want\n+to map more than one HTTP method to your Java method? You can use `@Path`_ annotation to specify a path\n+and use the HTTP method annotations without a path just to specify the HTTP methods to be mapped as follows.\n+\n+.. code-block:: java\n+\n+    class MyAnnotatedServiceClass {\n+        @Get\n+        @Post\n+        @Put\n+        @Delete\n+        @Path(\"/hello\")\n+        public HttpResponse hello() { ... }\n+    }\n+\n+.. _parameter-injection:\n+\n+Parameter injection\n+-------------------\n+\n+Let's see the example in the above section again.\n+\n+.. code-block:: java\n+\n+    class MyAnnotatedServiceClass {\n+\n+        @Get(\"/hello/{name}\")\n+        public HttpResponse pathvar(@Param(\"name\") String name) { ... }\n+\n+        @Get(\"regex:^/hello/(?<name>.*)$\")\n+        public HttpResponse regex(@Param(\"name\") String name) { ... }\n+    }\n+\n+A value of a parameter ``name`` is automatically injected as a ``String`` type by Armeria.\n+Which types are available for automatic injection? First, the following built-in types are available.\n+Armeria tries to convert a value to the specified type and ``IllegalArgumentException`` will be raised\n+if the conversion failed.\n+\n+- ``boolean`` (or ``Boolean``)\n+- ``byte`` (or ``Byte``)\n+- ``short`` (or ``Short``)\n+- ``integer`` (or ``Integer``)\n+- ``long`` (or ``Long``)\n+- ``float`` (or ``Float``)\n+- ``double`` (or ``Double``)\n+- ``String``\n+- ``Enum``\n+\n+``Enum`` type is also automatically converted if you annotate a parameter of your service method with\n+`@Param`_ annotation. If your ``Enum`` type is able to be handled in a case-insensitive way, Armeria\n+automatically converts the string value of a parameter to a value of ``Enum`` in a case-insensitive way.\n+Otherwise, case-sensitive exact match will be performed.\n+\n+.. code-block:: java\n+\n+    enum CaseInsensitive {\n+        ALPHA, BRAVO, CHARLIE\n+    }\n+\n+.. code-block:: java\n+\n+    enum CaseSensitive {\n+        ALPHA, alpha\n+    }\n+\n+.. code-block:: java\n+\n+    class MyAnnotatedServiceClass {\n+\n+        @Get(\"/hello1/{there}\")\n+        public HttpResponse hello1(@Param(\"there\") CaseInsensitive there) {\n+            // 'there' is converted in a case-insensitive way.\n+        }\n+\n+        @Get(\"/hello2/{there}\")\n+        public HttpResponse hello2(@Param(\"there\") CaseSensitive there) {\n+            // 'there' must be converted in a case-sensitive way.\n+            // So 'ALPHA' and 'alpha' are only acceptable.\n+        }\n+    }\n+\n+When the value of `@Param`_ annotation is not shown in the path pattern, it will be handled as a parameter\n+name of the query string of the request. If you have a service class like the example below and a user sends an\n+HTTP GET request with URI of ``/hello1?name=armeria``, the service method will get ``armeria`` as the value\n+of parameter ``name``. If there is no parameter named ``name`` in the query string, the parameter ``name``\n+of the method would be ``null``. If you want to avoid ``null`` in this case, you can use `@Default`_\n+annotation or ``Optional<?>`` class, e.g. ``hello2`` and ``hello3`` method in the example, respectively.\n+\n+.. code-block:: java\n+\n+    class MyAnnotatedServiceClass {\n+\n+        @Get(\"/hello1\")\n+        public HttpResponse hello1(@Param(\"name\") String name) { ... }\n+\n+        @Get(\"/hello2\")\n+        public HttpResponse hello2(@Param(\"name\") @Default(\"armeria\") String name) { ... }\n+\n+        @Get(\"/hello3\")\n+        public HttpResponse hello3(@Param(\"name\") Optional<String> name) {\n+            String clientName = name.orElse(\"armeria\");\n+            ...\n+        }\n+    }\n+\n+Armeria also provides `@Header`_ annotation to inject an HTTP header value into a parameter. The parameter\n+annotated with `@Header`_ is also specified as one of the built-in types as follows. `@Default`_ and\n+``Optional<?>`` are also supported.\n+\n+.. code-block:: java\n+\n+    class MyAnnotatedServiceClass {\n+\n+        @Get(\"/hello1\")\n+        public HttpResponse hello1(@Header(\"Authorization\") String auth) { ... }\n+\n+        @Post(\"/hello2\")\n+        public HttpResponse hello2(@Param(\"Content-Length\") long contentLength) { ... }\n+    }\n+\n+Moreover, the following classes are automatically injected into your parameter when you specify it on the\n+parameter list of your method.\n+\n+- RequestContext_\n+- ServiceRequestContext_\n+- Request_\n+- HttpRequest_\n+- AggregatedHttpMessage_\n+- HttpParameters_\n+\n+.. code-block:: java\n+\n+    class MyAnnotatedServiceClass {\n+\n+        @Get(\"/hello1\")\n+        public HttpResponse hello1(ServiceRequestContext ctx, HttpRequest req) {\n+            // Use the context and request inside a method.\n+        }\n+\n+        @Post(\"/hello2\")\n+        public HttpResponse hello2(AggregatedHttpMessage aggregatedMessage) {\n+            // Armeria aggregates every message received, then call this method with an aggregated message.\n+        }\n+\n+        @Get(\"/hello3\")\n+        public HttpResponse hello3(HttpParameters httpParameters) {\n+            // 'httpParameters' holds parameters which are parsed from a query string of a request.\n+        }\n+\n+        @Post(\"/hello4\")\n+        public HttpResponse hello4(HttpParameters httpParameters) {\n+            // If a request has a url-encoded form as its body, it can be accessed via 'httpParameters'.\n+        }\n+    }\n+\n+Handling exceptions\n+-------------------\n+\n+An exception may be raised from a service method, of course. Armeria provides `@ExceptionHandler`_\n+annotation to transform an exception into a response. You can write your own exception handler\n+by implementing ExceptionHandlerFunction_ interface and annotate your service object or method\n+with `@ExceptionHandler`_ annotation. Here is an example of an exception handler. If your exception\n+handler is not able to handle a given exception, you can call ``ExceptionHandlerFunction.fallthrough()``\n+to pass the exception to the next exception handler.\n+\n+.. code-block:: java\n+\n+    class MyExceptionHandler implements ExceptionHandlerFunction {\n+        @Override\n+        public HttpResponse handleException(RequestContext ctx, HttpRequest req, Throwable cause) {\n+            if (cause instanceof MyServiceException) {\n+                return HttpResponse.of(HttpStatus.CONFLICT);\n+            }\n+\n+            // To the next exception handler.\n+            return ExceptionHandlerFunction.fallthrough();\n+        }\n+    }\n+\n+To catch an exception from every method in your service object, annotate your class with the annotation.\n+\n+.. code-block:: java\n+\n+    @ExceptionHandler(MyExceptionHandler.class)\n+    class MyAnnotatedServiceClass {\n+\n+        @Get(\"/hello\")\n+        public HttpResponse hello() { ... }\n+    }\n+\n+To catch an exception from a single method in your service object, annotate your method with the annotation.\n+\n+.. code-block:: java\n+\n+    class MyAnnotatedServiceClass {\n+\n+        @Get(\"/hello\")\n+        @ExceptionHandler(MyExceptionHandler.class)\n+        public HttpResponse hello() { ... }\n+    }\n+\n+If there is no exception handler which is able to handle an exception, the exception would be passed to\n+the default exception handler. It handles ``IllegalArgumentException``, HttpStatusException_ and\n+HttpResponseException_ by default. ``IllegalArgumentException`` would be converted into ``400 Bad Request``\n+response, and the other two exceptions would be converted into a response with the status code which\n+they are holding. For another exceptions, ``500 Internal Server Error`` would be sent to the client.\n+\n+Conversion between an HTTP message and a Java object\n+----------------------------------------------------\n+\n+Converting an HTTP request to a Java object\n+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n+\n+In some cases like receiving a JSON document from a client, it may be useful to convert the document to\n+a Java object automatically. Armeria provides `@RequestConverter`_ and `@RequestObject`_ annotations\n+so that such conversion can be done conveniently.\n+You can write your own request converter by implementing RequestConverterFunction_ as follows.\n+Similar to the exception handler, you can call ``RequestConverterFunction.fallthrough()`` when your request\n+converter is not able to convert the request.\n+\n+.. code-block:: java\n+\n+    class MyRequestConverter implements RequestConverterFunction {\n+        @Override\n+        public Object convertRequest(ServiceRequestContext ctx, AggregatedHttpMessage request,\n+                                     Class<?> expectedResultType) throws Exception {\n+            if (expectedResultType == MyObject.class) {\n+                // Convert the request to a Java object.\n+                return new MyObject(request.content());\n+            }\n+\n+            // To the next request converter.\n+            return RequestConverterFunction.fallthrough();\n+        }\n+    }\n+\n+Then, you can write your service method as follows. Note that a request converter will work on the parameters\n+which are annotated with `@RequestObject`_.\n+\n+.. code-block:: java\n+\n+    @RequestConverter(MyRequestConverter.class)\n+    class MyAnnotatedServiceClass {\n+\n+        @Post(\"/hello\")\n+        public HttpResponse hello(@RequestObject MyObject myObject) {\n+            // MyRequestConverter will be used to convert a request.\n+            ...\n+        }\n+\n+        @Post(\"/hola\")\n+        @RequestConverter(MySpanishRequestConverter.class)\n+        public HttpResponse hola(@RequestObject MySpanishObject myObject) {\n+            // MySpanishRequestConverter will be tried to convert a request first.\n+            // MyRequestConverter will be used if MySpanishRequestConverter fell through.\n+            ...\n+        }\n+    }\n+\n+Armeria also provides built-in request converters such as, JacksonRequestConverterFunction_ for JSON\n+documents, StringRequestConverterFunction_ for text contents and ByteArrayRequestConverterFunction_\n+for binary contents. They will be applied after your request converters by default, so you can use these\n+built-in converters by just putting `@RequestObject`_ annotation on the parameters which you want to convert.\n+\n+In some cases, `@RequestObject`_ annotation may have a request converter as its value.\n+Assume that you have a Java class named ``MyRequest`` that it is usually able to be converted by\n+``MyDefaultRequestConverter``. But what if there is only one method which has a parameter of ``MyRequest``\n+that you have to convert it differently. In this case, you may specify a request converter with\n+`@RequestObject`_ annotation. In the example, ``MySpecialRequestConverter`` will be used first for\n+converting ``MyRequest``.\n+\n+.. code-block:: java\n+\n+    @RequestConverter(MyDefaultRequestConverter.class)\n+    class MyAnnotatedServiceClass {\n+\n+        @Post(\"/hello\")\n+        public HttpResponse hello(\n+            @RequestObject(MySpecialRequestConverter.class) MyRequest myRequest) { ... }\n+    }\n+\n+Converting a Java object to an HTTP response\n+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n+\n+Every object returning by the annotated service method is able to convert to an HTTP response message by","path":"site/src/sphinx/server-annotated-service.rst","position":417,"original_position":417,"commit_id":"1f1c15787ca0b0c9577c326ca288d1076d0324d9","original_commit_id":"1f1c15787ca0b0c9577c326ca288d1076d0324d9","user":{"login":"trustin","id":173918,"avatar_url":"https://avatars0.githubusercontent.com/u/173918?v=4","gravatar_id":"","url":"https://api.github.com/users/trustin","html_url":"https://github.com/trustin","followers_url":"https://api.github.com/users/trustin/followers","following_url":"https://api.github.com/users/trustin/following{/other_user}","gists_url":"https://api.github.com/users/trustin/gists{/gist_id}","starred_url":"https://api.github.com/users/trustin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/trustin/subscriptions","organizations_url":"https://api.github.com/users/trustin/orgs","repos_url":"https://api.github.com/users/trustin/repos","events_url":"https://api.github.com/users/trustin/events{/privacy}","received_events_url":"https://api.github.com/users/trustin/received_events","type":"User","site_admin":false},"body":"- returning by .. -> returned by an annotated ...\r\n- is able to convert to -> can be converted to","created_at":"2018-02-20T08:29:58Z","updated_at":"2018-02-20T08:52:45Z","html_url":"https://github.com/line/armeria/pull/1011#discussion_r169244966","pull_request_url":"https://api.github.com/repos/line/armeria/pulls/1011","author_association":"OWNER","_links":{"self":{"href":"https://api.github.com/repos/line/armeria/pulls/comments/169244966"},"html":{"href":"https://github.com/line/armeria/pull/1011#discussion_r169244966"},"pull_request":{"href":"https://api.github.com/repos/line/armeria/pulls/1011"}}},"pull_request":{"url":"https://api.github.com/repos/line/armeria/pulls/1011","id":169929234,"html_url":"https://github.com/line/armeria/pull/1011","diff_url":"https://github.com/line/armeria/pull/1011.diff","patch_url":"https://github.com/line/armeria/pull/1011.patch","issue_url":"https://api.github.com/repos/line/armeria/issues/1011","number":1011,"state":"open","locked":false,"title":"Add docs for annotated HTTP service","user":{"login":"hyangtack","id":8417787,"avatar_url":"https://avatars1.githubusercontent.com/u/8417787?v=4","gravatar_id":"","url":"https://api.github.com/users/hyangtack","html_url":"https://github.com/hyangtack","followers_url":"https://api.github.com/users/hyangtack/followers","following_url":"https://api.github.com/users/hyangtack/following{/other_user}","gists_url":"https://api.github.com/users/hyangtack/gists{/gist_id}","starred_url":"https://api.github.com/users/hyangtack/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hyangtack/subscriptions","organizations_url":"https://api.github.com/users/hyangtack/orgs","repos_url":"https://api.github.com/users/hyangtack/repos","events_url":"https://api.github.com/users/hyangtack/events{/privacy}","received_events_url":"https://api.github.com/users/hyangtack/received_events","type":"User","site_admin":false},"body":"Modifications:\r\n- `@Decorator` is able to annotate a class.\r\n- Add server-annotated-service.rst.","created_at":"2018-02-19T10:51:31Z","updated_at":"2018-02-20T08:52:46Z","closed_at":null,"merged_at":null,"merge_commit_sha":"d1983efae1a0759d271efed5c54018ff1222ff1b","assignee":null,"assignees":[],"requested_reviewers":[{"login":"minwoox","id":25103250,"avatar_url":"https://avatars2.githubusercontent.com/u/25103250?v=4","gravatar_id":"","url":"https://api.github.com/users/minwoox","html_url":"https://github.com/minwoox","followers_url":"https://api.github.com/users/minwoox/followers","following_url":"https://api.github.com/users/minwoox/following{/other_user}","gists_url":"https://api.github.com/users/minwoox/gists{/gist_id}","starred_url":"https://api.github.com/users/minwoox/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/minwoox/subscriptions","organizations_url":"https://api.github.com/users/minwoox/orgs","repos_url":"https://api.github.com/users/minwoox/repos","events_url":"https://api.github.com/users/minwoox/events{/privacy}","received_events_url":"https://api.github.com/users/minwoox/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[{"id":287373043,"url":"https://api.github.com/repos/line/armeria/labels/documentation","name":"documentation","color":"d4c5f9","default":false}],"milestone":{"url":"https://api.github.com/repos/line/armeria/milestones/95","html_url":"https://github.com/line/armeria/milestone/95","labels_url":"https://api.github.com/repos/line/armeria/milestones/95/labels","id":3091637,"number":95,"title":"0.59.0","description":"","creator":{"login":"trustin","id":173918,"avatar_url":"https://avatars0.githubusercontent.com/u/173918?v=4","gravatar_id":"","url":"https://api.github.com/users/trustin","html_url":"https://github.com/trustin","followers_url":"https://api.github.com/users/trustin/followers","following_url":"https://api.github.com/users/trustin/following{/other_user}","gists_url":"https://api.github.com/users/trustin/gists{/gist_id}","starred_url":"https://api.github.com/users/trustin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/trustin/subscriptions","organizations_url":"https://api.github.com/users/trustin/orgs","repos_url":"https://api.github.com/users/trustin/repos","events_url":"https://api.github.com/users/trustin/events{/privacy}","received_events_url":"https://api.github.com/users/trustin/received_events","type":"User","site_admin":false},"open_issues":7,"closed_issues":5,"state":"open","created_at":"2018-02-06T01:52:09Z","updated_at":"2018-02-20T03:12:03Z","due_on":null,"closed_at":null},"commits_url":"https://api.github.com/repos/line/armeria/pulls/1011/commits","review_comments_url":"https://api.github.com/repos/line/armeria/pulls/1011/comments","review_comment_url":"https://api.github.com/repos/line/armeria/pulls/comments{/number}","comments_url":"https://api.github.com/repos/line/armeria/issues/1011/comments","statuses_url":"https://api.github.com/repos/line/armeria/statuses/1f1c15787ca0b0c9577c326ca288d1076d0324d9","head":{"label":"hyangtack:feature/annotated_service_docs","ref":"feature/annotated_service_docs","sha":"1f1c15787ca0b0c9577c326ca288d1076d0324d9","user":{"login":"hyangtack","id":8417787,"avatar_url":"https://avatars1.githubusercontent.com/u/8417787?v=4","gravatar_id":"","url":"https://api.github.com/users/hyangtack","html_url":"https://github.com/hyangtack","followers_url":"https://api.github.com/users/hyangtack/followers","following_url":"https://api.github.com/users/hyangtack/following{/other_user}","gists_url":"https://api.github.com/users/hyangtack/gists{/gist_id}","starred_url":"https://api.github.com/users/hyangtack/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hyangtack/subscriptions","organizations_url":"https://api.github.com/users/hyangtack/orgs","repos_url":"https://api.github.com/users/hyangtack/repos","events_url":"https://api.github.com/users/hyangtack/events{/privacy}","received_events_url":"https://api.github.com/users/hyangtack/received_events","type":"User","site_admin":false},"repo":{"id":48430251,"name":"armeria","full_name":"hyangtack/armeria","owner":{"login":"hyangtack","id":8417787,"avatar_url":"https://avatars1.githubusercontent.com/u/8417787?v=4","gravatar_id":"","url":"https://api.github.com/users/hyangtack","html_url":"https://github.com/hyangtack","followers_url":"https://api.github.com/users/hyangtack/followers","following_url":"https://api.github.com/users/hyangtack/following{/other_user}","gists_url":"https://api.github.com/users/hyangtack/gists{/gist_id}","starred_url":"https://api.github.com/users/hyangtack/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hyangtack/subscriptions","organizations_url":"https://api.github.com/users/hyangtack/orgs","repos_url":"https://api.github.com/users/hyangtack/repos","events_url":"https://api.github.com/users/hyangtack/events{/privacy}","received_events_url":"https://api.github.com/users/hyangtack/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/hyangtack/armeria","description":"Asynchronous RPC/API client/server library built on top of Java 8, Netty 4.1, HTTP/2, and Thrift","fork":true,"url":"https://api.github.com/repos/hyangtack/armeria","forks_url":"https://api.github.com/repos/hyangtack/armeria/forks","keys_url":"https://api.github.com/repos/hyangtack/armeria/keys{/key_id}","collaborators_url":"https://api.github.com/repos/hyangtack/armeria/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/hyangtack/armeria/teams","hooks_url":"https://api.github.com/repos/hyangtack/armeria/hooks","issue_events_url":"https://api.github.com/repos/hyangtack/armeria/issues/events{/number}","events_url":"https://api.github.com/repos/hyangtack/armeria/events","assignees_url":"https://api.github.com/repos/hyangtack/armeria/assignees{/user}","branches_url":"https://api.github.com/repos/hyangtack/armeria/branches{/branch}","tags_url":"https://api.github.com/repos/hyangtack/armeria/tags","blobs_url":"https://api.github.com/repos/hyangtack/armeria/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/hyangtack/armeria/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/hyangtack/armeria/git/refs{/sha}","trees_url":"https://api.github.com/repos/hyangtack/armeria/git/trees{/sha}","statuses_url":"https://api.github.com/repos/hyangtack/armeria/statuses/{sha}","languages_url":"https://api.github.com/repos/hyangtack/armeria/languages","stargazers_url":"https://api.github.com/repos/hyangtack/armeria/stargazers","contributors_url":"https://api.github.com/repos/hyangtack/armeria/contributors","subscribers_url":"https://api.github.com/repos/hyangtack/armeria/subscribers","subscription_url":"https://api.github.com/repos/hyangtack/armeria/subscription","commits_url":"https://api.github.com/repos/hyangtack/armeria/commits{/sha}","git_commits_url":"https://api.github.com/repos/hyangtack/armeria/git/commits{/sha}","comments_url":"https://api.github.com/repos/hyangtack/armeria/comments{/number}","issue_comment_url":"https://api.github.com/repos/hyangtack/armeria/issues/comments{/number}","contents_url":"https://api.github.com/repos/hyangtack/armeria/contents/{+path}","compare_url":"https://api.github.com/repos/hyangtack/armeria/compare/{base}...{head}","merges_url":"https://api.github.com/repos/hyangtack/armeria/merges","archive_url":"https://api.github.com/repos/hyangtack/armeria/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/hyangtack/armeria/downloads","issues_url":"https://api.github.com/repos/hyangtack/armeria/issues{/number}","pulls_url":"https://api.github.com/repos/hyangtack/armeria/pulls{/number}","milestones_url":"https://api.github.com/repos/hyangtack/armeria/milestones{/number}","notifications_url":"https://api.github.com/repos/hyangtack/armeria/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/hyangtack/armeria/labels{/name}","releases_url":"https://api.github.com/repos/hyangtack/armeria/releases{/id}","deployments_url":"https://api.github.com/repos/hyangtack/armeria/deployments","created_at":"2015-12-22T12:16:46Z","updated_at":"2016-02-18T10:05:21Z","pushed_at":"2018-02-20T06:40:44Z","git_url":"git://github.com/hyangtack/armeria.git","ssh_url":"git@github.com:hyangtack/armeria.git","clone_url":"https://github.com/hyangtack/armeria.git","svn_url":"https://github.com/hyangtack/armeria","homepage":"http://line.github.io/armeria/","size":28024,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":null,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"line:master","ref":"master","sha":"1e1f965ca1869cd4d7662030cd6261a754df69c3","user":{"login":"line","id":13128444,"avatar_url":"https://avatars2.githubusercontent.com/u/13128444?v=4","gravatar_id":"","url":"https://api.github.com/users/line","html_url":"https://github.com/line","followers_url":"https://api.github.com/users/line/followers","following_url":"https://api.github.com/users/line/following{/other_user}","gists_url":"https://api.github.com/users/line/gists{/gist_id}","starred_url":"https://api.github.com/users/line/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/line/subscriptions","organizations_url":"https://api.github.com/users/line/orgs","repos_url":"https://api.github.com/users/line/repos","events_url":"https://api.github.com/users/line/events{/privacy}","received_events_url":"https://api.github.com/users/line/received_events","type":"Organization","site_admin":false},"repo":{"id":46251204,"name":"armeria","full_name":"line/armeria","owner":{"login":"line","id":13128444,"avatar_url":"https://avatars2.githubusercontent.com/u/13128444?v=4","gravatar_id":"","url":"https://api.github.com/users/line","html_url":"https://github.com/line","followers_url":"https://api.github.com/users/line/followers","following_url":"https://api.github.com/users/line/following{/other_user}","gists_url":"https://api.github.com/users/line/gists{/gist_id}","starred_url":"https://api.github.com/users/line/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/line/subscriptions","organizations_url":"https://api.github.com/users/line/orgs","repos_url":"https://api.github.com/users/line/repos","events_url":"https://api.github.com/users/line/events{/privacy}","received_events_url":"https://api.github.com/users/line/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/line/armeria","description":"Asynchronous RPC/REST library built on top of Java 8, Netty, HTTP/2, Thrift and gRPC","fork":false,"url":"https://api.github.com/repos/line/armeria","forks_url":"https://api.github.com/repos/line/armeria/forks","keys_url":"https://api.github.com/repos/line/armeria/keys{/key_id}","collaborators_url":"https://api.github.com/repos/line/armeria/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/line/armeria/teams","hooks_url":"https://api.github.com/repos/line/armeria/hooks","issue_events_url":"https://api.github.com/repos/line/armeria/issues/events{/number}","events_url":"https://api.github.com/repos/line/armeria/events","assignees_url":"https://api.github.com/repos/line/armeria/assignees{/user}","branches_url":"https://api.github.com/repos/line/armeria/branches{/branch}","tags_url":"https://api.github.com/repos/line/armeria/tags","blobs_url":"https://api.github.com/repos/line/armeria/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/line/armeria/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/line/armeria/git/refs{/sha}","trees_url":"https://api.github.com/repos/line/armeria/git/trees{/sha}","statuses_url":"https://api.github.com/repos/line/armeria/statuses/{sha}","languages_url":"https://api.github.com/repos/line/armeria/languages","stargazers_url":"https://api.github.com/repos/line/armeria/stargazers","contributors_url":"https://api.github.com/repos/line/armeria/contributors","subscribers_url":"https://api.github.com/repos/line/armeria/subscribers","subscription_url":"https://api.github.com/repos/line/armeria/subscription","commits_url":"https://api.github.com/repos/line/armeria/commits{/sha}","git_commits_url":"https://api.github.com/repos/line/armeria/git/commits{/sha}","comments_url":"https://api.github.com/repos/line/armeria/comments{/number}","issue_comment_url":"https://api.github.com/repos/line/armeria/issues/comments{/number}","contents_url":"https://api.github.com/repos/line/armeria/contents/{+path}","compare_url":"https://api.github.com/repos/line/armeria/compare/{base}...{head}","merges_url":"https://api.github.com/repos/line/armeria/merges","archive_url":"https://api.github.com/repos/line/armeria/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/line/armeria/downloads","issues_url":"https://api.github.com/repos/line/armeria/issues{/number}","pulls_url":"https://api.github.com/repos/line/armeria/pulls{/number}","milestones_url":"https://api.github.com/repos/line/armeria/milestones{/number}","notifications_url":"https://api.github.com/repos/line/armeria/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/line/armeria/labels{/name}","releases_url":"https://api.github.com/repos/line/armeria/releases{/id}","deployments_url":"https://api.github.com/repos/line/armeria/deployments","created_at":"2015-11-16T04:04:01Z","updated_at":"2018-02-20T01:03:38Z","pushed_at":"2018-02-20T07:57:04Z","git_url":"git://github.com/line/armeria.git","ssh_url":"git@github.com:line/armeria.git","clone_url":"https://github.com/line/armeria.git","svn_url":"https://github.com/line/armeria","homepage":"https://line.github.io/armeria/","size":30637,"stargazers_count":1118,"watchers_count":1118,"language":"Java","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":272,"mirror_url":null,"archived":false,"open_issues_count":86,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"forks":272,"open_issues":86,"watchers":1118,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/line/armeria/pulls/1011"},"html":{"href":"https://github.com/line/armeria/pull/1011"},"issue":{"href":"https://api.github.com/repos/line/armeria/issues/1011"},"comments":{"href":"https://api.github.com/repos/line/armeria/issues/1011/comments"},"review_comments":{"href":"https://api.github.com/repos/line/armeria/pulls/1011/comments"},"review_comment":{"href":"https://api.github.com/repos/line/armeria/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/line/armeria/pulls/1011/commits"},"statuses":{"href":"https://api.github.com/repos/line/armeria/statuses/1f1c15787ca0b0c9577c326ca288d1076d0324d9"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"trustin"}}