yahoo/parsec

Name: parsec

Owner: Yahoo Inc.

Description: null

Created: 2016-07-20 23:55:33.0

Updated: 2018-05-17 14:59:59.0

Pushed: 2017-11-22 08:56:38.0

Homepage: null

Size: 107590

Language: Java

GitHub Committers

UserMost Recent Commit# Commits

Other Committers

UserEmailMost Recent Commit# Commits

README

Parsec Build Status

Parsec is a collection of libraries and utilities built upon Gradle and Jersey2, with the reliance on RDL. It is designed to reduce the effort of building web service applications, allowing you to spend more quality time elsewhere. By using Parsec, the grunt work is handled so you can concentrate on the logic and implementation side of development. More importantly, Parsec also provides flexibility and abstraction such that you can easily enforce your own standard, and apply to the pipeline.

Parsec offers a standardized end-to-end solution to quickly bring web service applications from concept to production. The goal of Parsec is to:

If you are building a new project with Java, Parsec is definitely a good starting point.

Getting Started
Requirements

After having Java 1.8 and Gradle installed with the proper version, you must do a one time setup to allow you to create a Parsec project without a build.gradle script.

$ vim ~/.gradle/init.gradle, then enter the following code:

le.beforeProject { prj ->
rj.apply from: 'https://raw.githubusercontent.com/yahoo/parsec/master/parsec-template-plugin/installation/apply.groovy'

Create a New Project

To create a new Parsec project, run:

$ gradle createParsecProject -PgroupId='your.group.name' -PartifactId='your_project_name'

groupId refers to the namespace of your package, while the artifactId is your project name. If you do not specify the groupId or artifactId, you will be prompted to do so.

Create Schema

You need one or more RDL schema files to define your API specifications; they should be placed under src/main/rdl/ and be named as *.rdl. RDL is a machine-readable description of a schema that describes data types, as well as resources using those types.

You can start with this sample RDL file, save it as src/main/rdl/sample.rdl:

space your.group.name;
 sample;
ion 1;

 User struct {
string name (x_not_null="groups=insert", x_size="min=3,max=5,groups=update|insert");
string occupation (x_not_null="groups=update", x_size="min=4,groups=update|insert");
int32 age;
string id (x_null="groups=insert");


urce User GET "/users/{id}" {
int32 id;

expected OK;
exceptions {
    ResourceError INTERNAL_SERVER_ERROR;
    ResourceError BAD_REQUEST;
    ResourceError UNAUTHORIZED;
    ResourceError FORBIDDEN;
}


urce string POST "/users" {
User user (x_must_validate="insert");

expected OK;
exceptions {
    ResourceError INTERNAL_SERVER_ERROR;
    ResourceError BAD_REQUEST;
    ResourceError UNAUTHORIZED;
    ResourceError FORBIDDEN;
}


urce string PUT "/users/{id}" {
int32 id ;

User user (x_must_validate="update");

expected OK;
exceptions {
    ResourceError INTERNAL_SERVER_ERROR;
    ResourceError BAD_REQUEST;
    ResourceError UNAUTHORIZED;
    ResourceError FORBIDDEN;
}


Generate Code

After you have added your rdl files in the folder, you can use the command below to generate files:

$ gradle parsec-generate

Here is an example of the generated folder structure, based on the sample.rdl above:

ee build/generated-sources/
d/generated-sources/
java
??? your
    ???group
        ???name
            ???parsec_generated
                ??? ParsecApplication.java
                ??? ParsecErrorBody.java
                ??? ParsecErrorDetail.java
                ??? ParsecExceptionMapper.java
                ??? ParsecResourceError.java
                ??? ParsecValidationGroups.java
                ??? ParsecWebListener.java
                ??? ParsecWrapperServlet.java
                ??? ResourceContext.java
                ??? ResourceError.java
                ??? ResourceException.java
                ??? SampleHandler.java
                ??? SampleResources.java
                ??? SampleServer.java
                ??? User.java

rectories, 15 files

ee src/main/java/
main/java/
your
??? group
    ???name
        ??? DefaultApplication.java
        ??? DefaultExceptionMapper.java
        ??? DefaultResourceContext.java
        ??? DefaultWebListener.java
        ??? SampleClient.java
        ??? SampleClientImpl.java
        ??? SampleHandlerImpl.java

rectories, 7 files

Parsec generated Java server, model code, and Java client for the server. The generated code would include:

Java files are generated under ${baseDir}/build/generated-sources/java and the generated Java code are in sub-package .parsec_generated

Implement Handlers

Now you can start to implement your API by editing *HandlerImpl.java files. Here is an example of SampleHandlerImpl.java:

age your.group.name;

rt your.group.name.parsec_generated.User;
rt your.group.name.parsec_generated.SampleHandler;
rt your.group.name.parsec_generated.ResourceContext;

rt javax.servlet.http.HttpServletRequest;
rt javax.servlet.http.HttpServletResponse;


ampleHandlerImpl is interface implementation that implement SampleHandler interface.

ic class SampleHandlerImpl implements SampleHandler {

@Override
public User getUsersById(ResourceContext context, Integer id) {
    User user = new User();
    user.setName("user");
    return user;
}

@Override
public String postUsers(ResourceContext context, User user) {
    return "Post to user " + user.getName() + "!\n";
}

@Override
public String putUsersById(ResourceContext context, Integer id, User user) {
    return "put to user " + user.getName() + " by id " + id + "!\n";
}

@Override
public ResourceContext newResourceContext(HttpServletRequest request, HttpServletResponse response) {
    return new DefaultResourceContext(request, response);
}

Start your Server

Now you can start your server with:

$ gradle jettyRun

Check out your Swagger dashboard

Now you can run test with:

rl http://localhost:8080/api/sample/v1/users/1

e":0,"name":"user"}

rl -H 'Content-Type: application/json' -d '{"name":"user","age":10}' http://localhost:8080/api/sample/v1/users

ome to Parsec, user!
Use generated java client

Parsec friendly generates a simple client for your web service, including the interface and the implementation. Client implementation is base on com.ning.http.client.AsyncHttpClient, you can directly use it or modify it by your needs.

Here is the example of SampleClient.java, which provides methods to the APIs defined in src/main/rdl/sample.rdl.

age your.group.name;

rt java.util.concurrent.CompletableFuture;
rt your.group.name.parsec_generated.ResourceException;
rt your.group.name.parsec_generated.User;


ic interface SampleClient {
CompletableFuture<User> getUser(int id) throws ResourceException;
CompletableFuture<String> postUser(User user) throws ResourceException;
CompletableFuture<String> putUser(int id, User user) throws ResourceException;

License

Copyright 2016, Yahoo Inc. Copyrights licensed under the Apache 2.0 License. See the accompanying LICENSE file for terms.


This work is supported by the National Institutes of Health's National Center for Advancing Translational Sciences, Grant Number U24TR002306. This work is solely the responsibility of the creators and does not necessarily represent the official views of the National Institutes of Health.