Swagger, WADL or similar for the REST API?


#1

We are migrating from an old forum solution (based on Teamforge) over to Discourse, and we have a few scripts and tools that we’d like to re-write to use the Discourse REST API. Being notoriously lazy, I’m wondering if there is a Swagger, WADL or simiar machine-readable description of the API that I can use to generate clients?

I know @fantasticfears has an embryo of a Swagger definition on Github, which he posted about here: A community effort to improve Discourse’s documentation but as far as I can see it only describes which calls are available, not what they return. I’d like to generate a complete strongly typed library.

If no such description exists, I think it would save me time to write a Swagger specification for at least the parts of the API I need to work with. I’ll make sure to post about it here if I do.


(Erick Guan) #2

I didn’t improve the Swagger definition since then. But the team maintains a discourse_api gem which is the so called client.


#3

I’m not a particularly clever person, but from what I can see, that gem does not contain any information about what data is returned. Instead it relies on the API users somehow knowing what data is returned, which brings me back to my original problem of not having enough information to generate a strongly typed API.

Since my original post I’ve been playing around with Swagger a bit, and current-best-thinking is as follows:

  1. Use the source code of Discourse (not discourse_api) to get an idea about which data types are used in responses, and what data they share.
  2. Use discourse_api, the API documentation post and the Swagger specification created by @fantasticfears to get an idea about which requests exists, and what they do
  3. Write a complete Swagger specification including output data that can be used to generate a client in all languages supported by http://editor.swagger.io/ (and share it, of course!)

I’m sort of confident I can write such a specification, but I have no idea if I should.

So: Does anyone know any reasons doing this would be a bad idea?


(Sashko Stubailo) #4

I’ve been working on something similar with GraphQL! It turns out to be more strongly typed and actually more useful than Swagger in many cases. Read about the project here:

In fact, I just made this post from an app I wrote using my API!


(Jeff Atwood) #7

Do not post tests here. Use http://try.discourse.org for that.


(Sashko Stubailo) #8

Thanks, really appreciate the direction. Sorry about that.


(Erick Guan) #9

You are absolutely right. Though I think it’s a common problem for large RESTful website. It will takes so long time to just write the first draft of API :frowning: These endpoints are so many and return different attributes based on user identity.

This is a fairly nice way because that’s how I understand these endpoints. Beside that, Network tab in browser tool will show how Ember.js client talks with Rails. You do some actions and you can watch how it goes.

Postman are also useful to try different endpoints by API. routes.rb is the central point of endpoints, you can find every endpoints there. The hardest part is that you can’t discover what parameters you have to send.

It will be so nice if we have this specification. But It takes HUGE amount of time. If you insist, focus on topic list, users, category, badges, posts, topics, topic actions endpoints.


(Blake Erickson) #10

I personally am not a huge fan of Swagger, but I know people love it and swear by it. So if that is something that interests you go for it.

If your goal though is to re-write some scripts …

and …

If you are lazy I would focus more specifically on just one of your scripts you want to port over and figure out the 1 or 2 API calls you need to make to re-write the script and go from there.


#11

Thanks for the encouragement. I have now gotten started with it.

I took your advice and focused on what I need short term (categories, topics, posts) and I am now something like 30% of the way there (the rest should go faster since I now have an idea how to do it)

What I’ve done is to create a Swagger Specification, available at discourse_swagger/discourse_swagger.yml at master · erkist/discourse_swagger · GitHub (as of this writing it only supports site.json and categories.json)

This specification can be used to generate a Java API library (or any other supported language), which can then be invoked as below:

ApiClient client = new ApiClient();
client.setBasePath("http://192.168.56.2");

DefaultApi api = new DefaultApi(client);

((ApiKeyAuth) client.getAuthentication("api_username")).setApiKey("erki");
((ApiKeyAuth) client.getAuthentication("api_key"))
   .setApiKey("35b1416dda787a137dddca95170a549e0445507fcabcd009c09d3569cdb527b7");

Site site = api.getSiteInformation();
String nameOfFirstGroup = site.getGroups().get(0).getName();

Categories categoriesResponse = api.getCategories();
String nameOfFirstCategory = categoriesResponse.getCategoryList().getCategories().get(0).getName();

As you see the generated API is strongly typed, and the name and structure closely reflects the REST API responses.

I aim to continue expanding it a bit, but I’m not sure I’ll ever get to a full implementation. Still, if this helps anyone other than me, that would be awesome. And if someone wants to help, even better! And even if I’m the only user, I’m still satisfied since I’ve gotten the opportunity to learn YAML, Swagger, JSON Schema and parts of the Discourse source code :smiley:


(Erlend Sogge Heggen) #12

Is that due to the syntax, (which has since become the OpenAPI standard) or because of the tooling? I found SwaggerUI a bit off-putting, but ReDoc looks really great!


(Blake Erickson) #13

Mostly I couldn’t stand to look at the pages SwaggerUI generates.