redef fun get(req, res) do
var mentity = mentity_from_uri(req, res)
- if mentity == null then
- res.error 404
- return
- end
-
+ if mentity == null then return
res.json mentity_ratings(mentity)
end
redef fun post(req, res) do
var mentity = mentity_from_uri(req, res)
- if mentity == null then
- res.error 404
- return
- end
+ if mentity == null then return
var obj = req.body.parse_json
if not obj isa JsonObject then
- res.error 400
+ res.api_error(400, "Expected a JSON object")
return
end
var rating = obj["rating"]
if not rating isa Int then
- res.error 400
+ res.api_error(400, "Expected a key `rating`")
return
end
super APIHandler
redef fun get(req, res) do
+ var mentity = mentity_from_uri(req, res)
+ if mentity == null then return
var pdepth = req.int_arg("pdepth")
var cdepth = req.int_arg("cdepth")
- var mentity = mentity_from_uri(req, res)
- if mentity == null then
- res.error 404
- return
- end
var g = new InheritanceGraph(mentity, view)
res.send g.draw(pdepth, cdepth).to_svg
end
redef fun get(req, res) do
var mentity = mentity_from_uri(req, res)
- if mentity == null then
- res.error 404
- return
- end
+ if mentity == null then return
var metrics = mentity.collect_metrics(self)
if metrics == null then
- res.error 404
+ res.api_error(404, "No metric for mentity `{mentity.full_name}`")
return
end
res.json metrics
redef fun get(req, res) do
var mentity = mentity_from_uri(req, res)
- if mentity == null then
- res.error 404
- return
- end
+ if mentity == null then return
res.json mentity.hierarchy_poset(view)[mentity]
end
end
redef fun get(req, res) do
var mentity = mentity_from_uri(req, res)
- if mentity == null then
- res.error 404
- return
- end
+ if mentity == null then return
var lin = mentity.collect_linearization(config.mainmodule)
if lin == null then
- res.error 404
+ res.api_error(404, "No linearization for mentity `{mentity.full_name}`")
return
end
res.json new JsonArray.from(lin)
redef fun get(req, res) do
var mentity = mentity_from_uri(req, res)
+ if mentity == null then return
var arr = new JsonArray
if mentity isa MModule then
for mclassdef in mentity.mclassdefs do arr.add mclassdef
else if mentity isa MProperty then
for mpropdef in mentity.mpropdefs do arr.add mpropdef
else
- res.error 404
+ res.api_error(404, "No definition list for mentity `{mentity.full_name}`")
return
end
res.json arr
redef fun get(req, res) do
var mentity = mentity_from_uri(req, res)
+ if mentity == null then return
var dot
if mentity isa MClassDef then mentity = mentity.mclass
if mentity isa MClass then
var uml = new UMLModel(view, mentity)
dot = uml.generate_package_uml.write_to_string
else
- res.error 404
+ res.api_error(404, "No UML for mentity `{mentity.full_name}`")
return
end
res.send render_dot(dot)
if mentity == null then return
var source = render_source(mentity)
if source == null then
- res.error 404
+ res.api_error(404, "No code for mentity `{mentity.full_name}`")
return
end
res.send source
fun mentity_from_uri(req: HttpRequest, res: HttpResponse): nullable MEntity do
var id = req.param("id")
if id == null then
- res.error 400
+ res.api_error(400, "Expected mentity full name")
return null
end
var mentity = find_mentity(view, id)
if mentity == null then
- res.error 404
+ res.api_error(404, "MEntity `{id}` not found")
end
return mentity
end
var config: NitwebConfig
end
+redef class HttpResponse
+
+ # Return an HTTP error response with `status`
+ #
+ # Like the rest of the API, errors are formated as JSON:
+ # ~~~json
+ # { "status": 404, "message": "Not found" }
+ # ~~~
+ fun api_error(status: Int, message: String) do
+ json(new APIError(status, message), status)
+ end
+end
+
+# An error returned by the API.
+#
+# Can be serialized to json.
+class APIError
+ super Jsonable
+
+ # Reponse status
+ var status: Int
+
+ # Response error message
+ var message: String
+
+ # Json Object for this error
+ var json: JsonObject is lazy do
+ var obj = new JsonObject
+ obj["status"] = status
+ obj["message"] = message
+ return obj
+ end
+
+ redef fun to_json do return json.to_json
+end
+
redef class MEntity
# URL to `self` within the web interface.