docker-archive / docker-registry

This is **DEPRECATED**! Please go to https://github.com/docker/distribution
Apache License 2.0
2.88k stars 879 forks source link

[WIP] Automatically generate V2 API specification #868

Closed stevvooe closed 9 years ago

stevvooe commented 9 years ago

This changeset provides data structures and definitions describing the routes available in the V2 registry API. These route descriptors are structured to provide automated registration, for creating routers, in addition to complete documentation duty. It's also a possibility that this could be used to enumerate test coverage for server implementation.

Using this functionality, we've also developed a template to automatically generate and API specification for submission into docker core.

stevvooe commented 9 years ago

cc @jlhawn @dmcgowan @dmp42

Consider this PR a preflight for addition to the main client PR.

wking commented 9 years ago

On Thu, Dec 18, 2014 at 09:33:22PM -0800, Stephen Day wrote:

  • Automatically generate V2 API specification

It looks like the only connection between the internal specification for routeDescriptors and the implementation is:

  • for _, descriptor := range routeDescriptors {
  • router.Path(descriptor.Path).Name(descriptor.Name)
  • }

Is that a tight enough binding to be worth binding the spec into the implmentation? Or is it worth using someone else's spec language and having independent Swagger docs like docker/docker#9598 was starting on? On the other hand, machine parseable specs that exist (these) are better than machine parsable specs that are still in my queue (docker/docker#9598) ;). And apologies for the slow progress on that front, it's been a busy few weeks :p.

@thaJeztah also pointed out go-restful 1, but it doesn't look like you've used that here. Care to weigh in on why not?

stevvooe commented 9 years ago

@wking The entire v2 package has been designed to provide API definitions for use across specification compliant implementations. The binding between the spec and the implementation is limited to these definitions but I'd also like to employ these definitions to manage API implementation coverage. Ultimately, the checked version of the generated SPEC.md is the binding spec, so changes to the code that affect the specification will show up in the specification and be turned down if not allowed.

While using swagger was an option, I took the simpler route to just write out the definitions to generate a specification in the markdown format accepted by docker core documentation. The integration with Go's template system should allow one to generate code for other languages:

$ registry-api-descriptor-template pydefs.py.tmpl <<EOF
from collections import namedtuple

Error = namedtuple('Error', ["code", "message", "detail"])

{{range .ErrorDescriptors}}{{.Value}} = Error(
    code="{{.Code}}",
    message="{{.Message}}")
{{end}}
EOF

A similar template could be used to generate swagger documentation.

I've avoided go-restful, or any other web framework for that matter, to restrict the number of external dependencies. net/http is sufficient for the needs of the registry and keeps the bar for future contributions low, since one doesn't have to know a particular framework to work with the project.

dmp42 commented 9 years ago

LGTM