Skip to content

The Shortest Tutorial

Fernando Ultremare edited this page Oct 24, 2015 · 19 revisions

All the code (and tags for each step) of this tutorial can be found in this project.

1 - Basic Setup

The easiest way to bootstrap an YAWP! API is to create a project from it's maven archetype:

mvn archetype:generate \
  -DarchetypeGroupId=io.yawp \
  -DarchetypeArtifactId=yawp \
  -DarchetypeVersion=LATEST \
  -DgroupId=yawptut \
  -DartifactId=yawptut \
  -Dversion=1.0-SNAPSHOT

Then, start the devserver:

cd yawptut
mvn appengine:devserver

If everything went without errors, you should have an example API to test:

curl -H "Content-type: application/json" -X POST -d "{ name: 'daniel' }"  http://localhost:8080/api/people ; echo
curl -H "Content-type: application/json" -X GET http://localhost:8080/api/people ; echo

2 - Simple Endpoint

If you check inside te src/main folder of the generated app, you'll find a package yawptut.models and inside a java file called Person.java. This is the basic structure of an YAWP! Endpoint:

@Endpoint(path = "/people")
public class Person {

    @Id
    private IdRef<Person> id;

    @Index
    private String name;

    public IdRef<Person> getId() {
        return id;
    }

    public void setId(IdRef<Person> id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

With this you have all the basic rest operations:

curl -H "Content-type: application/json" -X POST -d "{ id: '/people/1', name: 'daniel' }"  http://localhost:8080/api/people ; echo
curl -H "Content-type: application/json" -X GET http://localhost:8080/api/people ; echo
curl -H "Content-type: application/json" -X GET http://localhost:8080/api/people/1 ; echo
curl -H "Content-type: application/json" -X PUT -d "{ id: '/people/1', name: 'chnaged daniel' }"  http://localhost:8080/api/people/1 ; echo
curl -H "Content-type: application/json" -X PATCH -d "{ name: 'chnaged daniel' }"  http://localhost:8080/api/people/1 ; echo
curl -H "Content-type: application/json" -X DELETE http://localhost:8080/api/people/1 ; echo

3 - The Javascript Client

YAWP! also provides a Javascript client, all http actions are supported. To test it, inside the folder src/main/webapp create a html file called yawp-client.html with this content:

<html>
    <head>
        <meta charset="utf-8">
        <title>YAWP! js client</title>

        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
        <script src="https://rawgit.com/feroult/yawp/master/yawp-core/src/main/js/yawp.js"></script>
    </head>
    <body>
    </body>
</html>

Then open your javascript console and type:

yawp('/people').create({ id: '/people/1', name: 'daniel' }).done(function() {
    yawp('/people/1').fetch(function(person) { console.log('person:', person.name); });
});

The output should be:

person: daniel

4 - Adding Custom Actions

Inside your editor create the package yawptut.actions. Then add a class called PersonAction:

public class PersonAction extends Action<Person> {

    @PUT("upper")
    public void upper(IdRef<Person> id) {
        Person person = id.fetch();
        person.setName(person.getName().toUpperCase());
        yawp.save(person);
    }
}

Test it from the javascript client:

yawp('/people/1').put('upper').done(function(response) {
    console.log('response:', response);
});

Check the result (name in uppercase):

yawp('/people/1').fetch(function(person) {
    console.log('name:', person.name);
});

5 - Creating Relationships

To create simple relationship, go to your yawptut.models package and add class called Job:

@Endpoint(path = "/jobs")
public class Job {

    @Id
    private IdRef<Job> id;

    @Index
    private String name;

    public IdRef<Job> getId() {
        return id;
    }

    public void setId(IdRef<Job> id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Go to your Person model again and add a relationship property:

(...)
private IdRef<Job> jobId;

public IdRef<Job> getJobId() {
    return jobId;
}

public void setJobId(IdRef<Job> jobId) {
    this.jobId = jobId;
}
(...)

Now you should be able to work with relationships like this:

yawp('/jobs').create({ name: 'programmer' }).done(function(job) {
    yawp('/people/1').patch( { jobId: job.id } ).done(function(person) {
        console.log('patched person:', person);
    });
});

6 - Protecting you API

To protect your API create a Shield. Go to the yawptut package again and create a subpackage called shields. Then add a java class called PersonShield:

public class PersonShield extends Shield<Person> {

    @Override
    public void show(IdRef<Person> id) {
        allow();
    }

}

Now, you'll only be able to show a person. Check if you can create another person:

curl -H "Content-type: application/json" -X POST -d "{ name: 'james' }"  http://localhost:8080/api/people ; echo

The result should be:

{"status":"error","message":"The resquest was not allowed by the endpoint shield yawptut.shields.PersonShield"}

This detailed message won't be visible in the production environment.

7 - Testing

Your project also comes with a preconfigured qunit test suite. To run it, first open your Endpoint to all actions. Change the class yawptut.PersonShield to this:

public class PersonShield extends Shield<Person> {

    @Override
    public void defaults() {
        allow();
    }
}

Open this address: http://localhost:8080/test/all.html

8 - Other APIs

Yawp also come with other APIs, that you should be using further as your API grows, they are: Query, Hooks and Transformer APIs. At the project home you can get more information on how to use them.