- What is go-raml
- Supported RAML Versions
- Install & Build in Development
- Code Generation
- Usage
- Generating Server
- Generating Client
- Using Generated Code
- Specification File
- Viewing and Editing RAML file
- Contribute
- Roadmap
- RAML to Code Translation
When creating and maintaining api's, there are two approaches:
-
Design first
You design the api, all methods, descriptions and types from the api point of view. Afterwards, you generate all the boilerplate code and documentation to bootstrap the code.
-
Code first
When modifying the implementation, the interface definitions need to be kept in sync. Besides the good practice of keeping your specification up to date, it is used by other tools to generate clients, documentation, ...
This tool supports both (or at least, this is on the roadmap). As a specification format, it uses RAML 1.0 .
Only RAML version 1.0 RC is supported.
Currently there are still some limitations on the RAML 1.0 features that are supported.
make sure you have at least go 1.6 installed !
go get -u github.com/Jumpscale/go-raml
Install godep
as package manager, we need it for vendoring tool
$go get -u github.com/tools/godep
Install go-bindata, we need it to compile all resource files to .go file
go get -u github.com/jteeuwen/go-bindata/...
To rebuild APIDocs files to .go file
cd $GOPATH/src/github.com/Jumpscale/go-raml
sh build_apidocs.sh
Build go-raml and all resource files
cd $GOPATH/src/github.com/Jumpscale/go-raml
sh build.sh
Internally, go templates are used to generate the code, this provides a flexible way to alter the generated code and to add different languages for the client.
To use it on the commandline, just execute go-raml
without any arguments, it will output the help on the stdout.
To invoke the codegeneration using go generate
, specify the generation in 1 of your go source files:
//go:generate go-raml ...
go-raml needs to be on the path for this to work off course.
go-raml
able to generate Go & Python server.
Generated server will listen on port 5000
To generate the Go code for implementing the server in first design approach, execute
go-raml server -l go --dir /gopath/src/github.com/mycompany/myapi --ramlfile api.raml --import-path github.com/mycompany/myapi
--dir
specify generated code directory. Except you really know what you do, use $GOPATH as root directory. In above example $GOPATH is /gopath.
--ramlfile
is the path RAML file
--import-path
is the root import path of the code. Generated code contains sub packages and need it to properly import code from another packages
To generate the Flask/Python code for implementing the server, execute
go-raml server -l python --dir ./result_directory --ramlfile api.raml
--language, -l "go" Language to construct a server for
--dir "." target directory
--ramlfile "." Source raml file
--package "main" package name
--no-main Do not generate a main.go file
--no-apidocs Do not generate API Docs in /apidocs/?raml=api.raml endpoint
--import-path "examples.com/ramlcode" import path of the generated code
go-raml client --language go --dir ./result_directory --ramlfile api.raml
A go 1.5.x compatible client is generated in result_directory directory.
go-raml client --language python --dir ./result_directory --ramlfile api.raml
A python 3.5 compatible client is generated in result_directory directory.
Both servers have simple HTML home page that can be accessed in http://localhost:5000. it provide simple description of the API server and link to auto generated API Documentation powered by api-console
Generated go server can be used as your API server skeleton. It gives you routing code, implementation skeleton, simple request validation, and all struct based on raml types and request/response body. You can then extend the generated code to fit your need.
Generated code details:
- an optional main file which contain routing code and other inialization code
- Interfaces files, contain routing code which mapped one to one with RAML resources. It always regenerated
- Interface implementation. It is code skeleton of the resource implemetation, only generated when the file is not present. So you can easily modify it
- Struct for RAML types and request/response body, only generated when the file is not present.
- Validation code
- Helper files
The generated server uses Gorilla Mux as HTTP request multiplexer.
install required packages
$go get github.com/gorilla/mux
$go get gopkg.in/validator.v2
$go get github.com/justinas/alice
Build the code
go build ./...
Execute it
./binary_name
The server will then run in port 5000, you can go to http://localhost:5000 to see default html page as described above
The generated code is utilizing Flask Blueprint to give you modular flask code.
Generated code details:
- main file named app.py which initialize the app
- one bluperint/module for each root RAML resource
- helper file
- requirements.txt which contains list of packages needed to run the app.
Install needed packages
pip3 install -r requirements.txt
You might want to install it inside virtualenv
Run the code
python3 app.py
The server will then run in port 5000, you can go to http://localhost:5000 to see default html page as described above
Generated go client library can be used directly as modular package of your project.
It has AuthHeader
field, which if not empty will be used as value of Authorization
header on each request.
Generated python client library only need python-requests as dependency.
It has set_auth_header
method to set Authorization
header value on each request.
Besides generation of a new RAML specification file, updating an existing raml file is also supported. This way the raml filestructure that can be included in the main raml file is honored.
go-raml spec ...
There are many ways to view and edit RAML file:
- API Workbench is an atom package for designing, building, testing, documenting and sharing RESTful HTTP APIs
- Vim : it is enough for simple purpose
When you want to contribute to the development, follow the contribution guidelines.
v0.1
- Generation of the server using gorilla mux
- Generation of a go client
- Generation of a python 3.5 client
- Generation of a python flask server
v0.2
- OAuth 2.0 support
- Input validation according to the RAML type definitions
v0.3
- Possibility to generate a default server implementation to MongoDB
v0.4
- Generation of a new RAML specification file
v0.5
- Update of a RAML specification file
Below are incomplete description about how we translate .raml file into code.
types is mapped to struct.
Some rules about properties naming:
- capitalizing first character of the properties.
- json tag is the same as property name
File name is the same as types name with lowercase letter. struct name = types name.
Raml | Go
----------- | -----------
string | string
number | float
integer | int
boolean | bool
date | Date
enum | []string
file | string
sometype[] | []sometype
sometype[][]| [][]sometype
Union | interface{}
Request Body and response body are mapped into structs and following the same rules as types.
struct name = [Resource name][Method name][ReqBody|RespBody].
RequestBody generated from body node below method.
ResponseBody generated from body node below responses.
Resource in the server is mapped to:
-
interface:
- file name = [resource]_if.go
- always be regenerated
- interface name = [resource]Interface
-
API implementation that implements the interface
- file name = [resource]_api.go
- only generated when the file is not present
- struct name = [resource]API
-
routes for all necessary routes:
- func name = [Resource]InterfaceRoutes
Code related to requests headers are only generated in the Client lib. All functions have arguments to send any request header, the current client lib will not check the headers against the RAML specifications.
Response headers related code is only generated in the server in the form of commented code, example:
// uncomment below line to add header
// w.Header.Set("key","value")
All client library functions have arguments to send Query Strings and Query Parameters, the current client lib will not check it against the RAML specifications.
The generated code in the server is in the form of commented code:
// name := req.FormValue("name")
Validation | Go | Python
------------------------------- | ------------- | ----------- minLength | v | v maxLength | v | v pattern | v | v minimum | v | v maximum | v | v format | x | x multipleOf | v | v array field minItems | v | v array field maxItems | v | v array field uniqueItems | v | x array Type minItems | v | x array Type maxItems | v | x array Type uniqueItems | v | x