|
As a curiosity, how do you feel about languages/frameworks where APIs can be pretty self-documenting? For example, Java/JAX-RS creates pretty self-documenting APIs: @Path("/people")
public class PeopleApi {
@Path("{personId}")
@GET
public Person getPerson(@PathParam("personId") int personId) {
return db.getPerson(personId);
}
}
It's easy to generate a spec for a JAX-RS class because it has the paths, parameters, types, etc. right there. There's a GET at /people/{personId} which returns a Person and takes a path parameter personId which is an integer.If we're talking about a Go handler which doesn't have that information easily accessible, I understand wanting to start with a spec: func GetPerson(w http.ResponseWriter, r *http.Request) {
personId, _ := strconv.Atoi(r.URL.Path.something)
person := db.GetPerson(personId)
w.Write(json.marshal(person))
}
func GetPerson(c echo.Context) error { //or with something like Echo/Gin
id := c.Param("id")
person := db.GetPerson(id)
return c.Json(http.StatusOK, person)
}
In Go's case, there's nothing which can tell me what the method takes as input without being able to reason about the whole method. With JAX-RS, it's easy reflect on the method signature and see what it takes as input and what it gives back, but that's not available with Go (with the Go tools that most people are using).This isn't meant as a Go/Java debate, but more a question of whether some languages/frameworks basically already give you the spec you need to the point where you can easily generate an OpenAPI spec from the method definition. Part of that is that the language has types and part of it is the way JAX-RS does things such that things you're grabbing from the request become method parameters before the method is called rather than the method just taking a request object. JAX-RS makes you define what you want to send and what you want to receive in the method signature. I totally agree that people should start with thinking about what they want from an API, what to send, and what to receive. But is starting with OpenAPI something that would be making up for languages/frameworks that don't do development in that way naturally? ---------- Just to show I'm not picking on Go, I'm pretty sure one could create a Go framework more like this, I just haven't seen it: type GetPersonRequest struct {
Request `path:/people/{personId}`
PersonId int `param:path`
}
func GetPerson(personRequest GetPersonRequest) Person {
return db.GetPerson(personRequest.PersonId)
}
I think you'd have to have the request object because Go can annotate struct fields (with struct tags), but can't annotate method parameters or functions (but I could be wrong). The point is that most languages/frameworks don't have the spec information in the code in an easy way to reflect on like JAX-RS, ASP.NET APIs, and some others do. |
Looking for the handler for ˋGET /foo/{fooID}/barˋ is terrible in a codebase using annotations.