Creating an API
REST APIs provide a structured, standardized way to expose and access data and functionalities over the internet, making it easier to integrate different software systems. REST (Representational State Transfer) means that the server does not store any state about the client session. Each request is independent from previous ones.
Creating an API with Genie Framework is as easy as adding a set of endpoints linked to a specific functionality. Moreover, it is possible to automatically generate an API documentation page with Swagger.
API endpoints
An API is comprised of multiple endpoints, each of which requires:
- A route that defines the URL path, parameters, handler, and HTTP method to access a resource.
route("/api/hello/:name", greet, method=GET)
- A handler function that processes the request and returns a response
function greet()
"Hello $(params(:name))"
end
Any information to be sent to the API is passed as a parameter in the URL path (GET request) or in the body (POST request) of the request. This can be then extracted by the handler with the params
call.
Continuing with the statistical analysis app in the Your first app example, suppose you want the app to return a vector of random numbers of length N
at /numbers/:N
. First, add an api_numbers
function to the controller:
using GenieFramework.Genie.Renderers.Json: json
function api_numbers()
json("x" => gen_numbers(payload(:N))))
end
It is convenient to format the response as a JSON dictionary to make it easier to consume by third parties.
Then, add a route for the endpoint in app.jl
:
route("/api/numbers/:N::Int", AnalysisController.api_numbers, method=GET)
Notice that it is also possible to specify the type of the parameter in the URL with the usual ::Type
syntax.
To check that the endpoint is working, simply open a browser at /api/numbers/<N-value>
.
Documenting the API
It is often a good idea to add a documentation page to make the API endpoints discoverable and easier to use. You can use the SwaggUI.jl
and SwaggerMarkdown
packages to individually document each endpoint and automatically generate a documentation page.
First, use the @swagger
macro to add a docstring to a route with the endpoint specification following the OpenAPI format:
using SwagUI, SwaggerMarkdown
@swagger """
/api/predict/{id}:
get:
description: Predict the MEDV of a house.
parameters:
- in: path
name: N
required: true
description: Length of the random number vector.
schema:
type: integer
responses:
'200':
description: OK
"""
route("/numbers/:N::Int", AnalysisController.api_numbers, method=GET)
Second, add a handler that builds the documentation page:
function api_docs()
info = Dict{String,Any}()
info["title"] = "Statistic analysis API"
info["version"] = "1.0.5"
openApi = OpenAPI("3.0", info)
swagger_document = build(openApi)
render_swagger(swagger_document)
end
Finally, add a route to the documentation page:
route("/api/docs", api_docs)