To create an API with FoxxGenerator, first draw a statechart that represents your API. In this statechart, your states can have one of the following types:
- Entity: This state represents something that has an identity and an arbitrary number of (optionally nested) attributes.
- Repository: A repository can store entities.
Connect these states with transitions. When you have modeled your statechart in a way that it can fulfill all your use cases, it is time to classify your transitions. For every transition you have to decide which of the following type it follows:
follow: This is a transition that you can just follow from one state to the next.
connect: This is a point of extension where you can create a transition at runtime. In order to be able to follow this transition, you have to add a
followtransition as well.
disconnect: With this transition you can remove a transition created with
modify: This is a transition that can only be created from an entity to itself. It is used to modify the state of this entity.
You can now translate this annotated statechart into the DSL of FoxxGenerator to create your API.
Setting up a Foxx application with FoxxGenerator.
First, create a Foxx application as described in Foxx's manual. In the folder of your Foxx app, you can now install FoxxGenerator with
npm install foxx_generator. In the same way you would add a controller to your Foxx application, you can now add a FoxxGenerator to your application: In the file that would normally contain your FoxxController, add the following:
var FoxxGenerator = GeneratorJoi =generator;generator = 'name_of_your_app'// To learn more about media types, see belowmediaType: 'application/vnd.siren+json'applicationContext: applicationContext;// Insert transition definitions here// Insert states heregenerator;
For more information on how to choose a media type, see the section about Media types. Now you can define the transitions you used in your statechart and then add the states and the transitions between them.
Defining the transitions
Every transition needs the following attributes:
- A name for the transition that you can use when you want to add a transition of this type.
type: One of the types described above.
to: Is the target of this transition one or more states? For a
connecttransition this for example determines if you can only connect one state to it or more than that. Acceptable values are
/**) that will be used for the documentation. The first line should be a short summary, all other lines will be used for a long description. An example for that would be the following transition definition:
/** Show details for a particular item** Show all information about this particular item.*/generator;
disconnect transition you additionally have to determine which
follow transition can be used to follow the created transition. This is done with
as and the name of the transition.
You can also add
parameters to the transition, if in the transition process you need additional information from the user of the API. Each of the parameters needs to be a value object defined with Joi. For example:
/** Modify the title of the entity**/generator;
You can also define a
Adding states and transitions
Now you can add states and transitions to your API. Every state has a name, a type and a number of outgoing transitions. The type is one of the above described ones – either
service. Every transition needs information about where it leads to and via which transition type. The transition type needs to be defined as described above. Simple example:
Some states take additional information: Entities need to know which repository they are contained in (via
containedIn) and repositories need to know which entities they contain (via
States can also have a superstate. This can be done by providing
superstate with the name of the state that should be the superstate as a string. The superstate is provided to the service via a third parameter in its action. It is an object that has a key called
superstate where the value depends on the superstate's type:
- If the superstate is an entity, it has a key
entitywhere the value is the entity and a key
repositorywhich is the Foxx.Repository in which the entity is saved.
- If the superstate is a repository, it has a key
repositorywhich contains the Foxx.Repository.
An entity can be
parameterized (by setting its attribute
true) which means that there is not only one state of that type, but there can be an arbitrary amount – each of them is identified by a parameter. This is usually the case with entities that are stored in a repository.
It also takes an object of attributes which describe the representation of the entity. Each of the attributes needs to be a value object defined with Joi.
Example for an entity:
A service needs to describe what it does, this is done with an
action which is a function that takes a request and a response in the same way that a FoxxController route does. The default HTTP verb for a service is a
post, it can be changed by setting the
FoxxGenerator currently only supports siren which is a media type without application semantics. Use the media type
application/vnd.siren+json. We plan to support HAL with an extension for forms in the near future.
During your development, FoxxGenerator will generate an interactive documentation alongside the API. You can use this in an iterative development style to check after each step if the API is as you expected it to be. The documentation allows you to try out each of the generated endpoints. The API documentation can be found in the admin interface of ArangoDB and looks a little like this:
If you click on one of the routes, you can try it out:
- An example for a Siren API generated with FoxxGenerator can be found here
To check the project for linting errors, run
npm run jshint.