Swagger best practices - swagger

I am currently defining a Rest API and I intend to use Swagger to document it.
I've already started to define my API specifications with the Open Api Specification in YAML into the Swagger-Editor.
Then, I understand that I will provide that file to the Swagger-codegen to generate a server implementation, and also to the Swagger-UI (whose statics files will be previously paste to my server) to expose the interactive documentation .
According to Swagger, this is the top-down approach.
But later, I will probably need to modify this API, and I want to do it via by this tediously YAML file previously defined, to keep the API easily modifiable by anyone (and Language-agnostic).
Does the way to do this is to modify the definition file and then re-use Swagger-codegen ? By this approach, I guess so that I can't even lightly modify the API directly in the implementation server code without risking to have a out of date documentation.
And If I chose to do the bottom-up approach (via Swagger-core annotation), I will restrain all my further modifications to occur in the implementation server code, and my initial definition file will never be usable again.
So another question would be : Is there a common way to deal with Swagger when we want to modify the API both via the specification file and via the implementation server code (I suppose that the file that Swagger-core can generate me from my code, will never looks like my initial one that I defined by hand).

To maintain the API documentation, the best course of action that i can suggest is to follow a hybrid approach.
Initially, when you have to do bulk development, go for the top down approach. This will reduce the initial set up and coding effort. That's the basic idea behind any codegen.
Then, when it comes to maintaining the APIs, or adding a few new ones every day (or week), follow the bottom up approach. You will already have the previous code, the only thing you'll need to do is add some more annotations or API definitions.
Going for top-down iteratively defeats the purpose of code maintenance. Boiler plates and self generated code are there to give you a quick start, not for sustenance.

My opinion may be biased.
For API client, there should not be a need to customize it in most cases. If you find that you need to customize it to meet your requirement, it may worth starting a discussion via https://github.com/swagger-api/swagger-codegen/issues/new (and also please check what are the options available to customize the output, e.g. for PHP, run java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar config-help -l php)
For server stub, ideally the developers only need to focus on the business/application logic and regenerate the server stub when adding/deleting/updating endpoints (but I don't think all the server stubs can achieve that yet)
Disclaimer: I'm the top contributor to Swagger Codegen

Related

Generated nodejs server stub is missing routing

I wanted to try out the code first approach with an OpenAPI spec. For testign purposes I treied the Pet Store Example from SwaggerHub.
In the generated Code I noticed, that there is no logic involving routing.
I also noticed that the code in the service folder is not even used when I run the nodejs server (changing values of example data changes nothing in the output. The API seems to run a swaggerhub server.
Do I have a missunderstanding here, what the swagger code gen does?
On the other hand the client code generation looks how I woudl expect it. Instead of creating rest requests in my client I only have to execute methods of the services.
Based off your question, I would argue you're actually doing a "design-first" approach.
Code-first is when you have an existing codebase/service and you then create your documentation after (whether it is generated or hand written).
A design-first approach is when you create your documentation first, and THEN build out your code. If you have an OpenAPI document, and you're using Swagger codegen to create some code, then you're doing design-first.
As for your question involving routing, all Swagger codegen will do for you is generate some boilerplate code based off of your OpenAPI document. It will not add any business logic, or even route the API calls for you. It is then on you to implement all this logic after the fact.

Breeze save bundle format

I am using Breeze JS and would like to implement a server with full CRUD functionality using Progress Openedge. The Breeze website talks a lot about being able to write your own server implementation but I can find no information describing the format of a save bundle that Breeze sends to the server. Does anyone know of any documentation or schema?
The documentation for this is buried in the DataServiceAdapters page. Look about halfway down, under the heading saveChanges (saveContext, saveBundle) -> promise.
There's an example of what the JSON looks like in this SO answer.
The SaveBundle is not documented for a very good reason: it has no definition in BreezeJS!
It could be any serialized object that your server requires to satisfy yoursaveChanges work flow. You can see that this is true by examining the a60_abstractDataServiceAdapter.js source in github:
proto._prepareSaveBundle = function (/*saveContext, saveBundle*/) {
...
throw new Error("Need a concrete implementation of _prepareSaveBundle");
};
Breeze does ship with an implementation b00_breeze.dataService.webApi that satisfies the expectations of the companion Breeze ASP.NET Web API helper classes such as ContextProvider. This implementation is worth studying if you decide to write your own server support code.
But it is only one of many possible implementations. An OData web server, for example, requires an entirely different package and format for "$batch" change-set saves. Only you know what's right for your "Progress Openedge" server.
All that said, we do delve into some critical aspects of the SaveBundle destined for Breeze Web API services in the documentation for "ContextProvider".
Feel free to follow-up with more specific questions after you've read that.

Why does HotTowel include Breeze?

This may sound like a dumb question on the surface, but why does the Hot Towel SPA Template include Breeze at all?
I've been spending the last few days learning Hot Towel and its dependencies, and as far as I can tell, nothing in the template actually uses Breeze. Perhaps that is going to change with some future release?
Sure, Breeze is a good library. But it's bound to CRUD methodology and requires you design your ApiControllers a particular way. (Metadata, SaveChanges, etc.) see here
It also guides you to Entity Framework. While this is more of a soft-dependency, since Breeze also shows a sample without it, it still guides you down a similar pattern of implementation using a modified repository pattern.
If you are using a NoSQL datastore, or CQRS patterns instead of CRUD, then Breeze becomes very difficult to use. There are alternative libraries for data access that work well in this style, such as AmplifyJS.
But the rest of Hot Towel is excellent! I especially like Durandal. So the question begs, if the template isn't actually doing any data access - why include any data access component at all? It would be better to ship it without Breeze, and if the end-user wants to use Breeze, or Amplify, or whatever - then so be it. The rest of Hot Towel would continue to shine as a great SPA implementation.
Matt - Good question. Since I created it I guess I should answer :)
When I built the template I had a focus on providing enough to get folks going with the right tools, and just enough starter code to guide the way. I did not want anyone ripping out code. I'm not a fan of templates that start you down a path and make you remove tons of files and code and change direction. Those are samples.
Samples are good. In fact, samples can be excellent (like the other templates, which I feel are more like samples). Those serve another purpose: to show how you can do things.
Back to the Hot Towel template ...if I include code that uses Breeze, I would be tempted to add a datacontext.js and a model.js on the client. They would contain data access code and code to extend the models on the client. Then I would be tempted to add a controller, some server side models, an ORM and a database. Once there, I'd want to use the data in multiple screens, which leads me to more Knockout and caching with Breeze. Then I might be tempted to add editing, which would lead to change tracking. Soon I have a full blown app. Or more conservatively, I have a sample again. While these approaches would provide more guidance on how to put these together, they would not help you "get started" with a template where you can just start building and adding your own code. If I stop short of some of these features, it's still walking down a road that requires you to change how I did it.
As it stands today, HotTowel is pretty darn close to a template in the truest sense. You create a new project and you are off and adding your own code.
You could argue (and you may be) that Breeze shouldn't be in there since I don't use it in the template. Nor do I use moment.js, BTW. However, I argue that they are both excellent libraries that I would not want to build a CRUD based SPA without them. Breeze is flexible, as you suggest, so you don't have to walk a specific path.
The best way to understand the value of Breeze is to build an app that has its features but without Breeze. Then you can see how much code that takes and how involved it is. For one such example, see my intermediate level SPA course at Pluralsight where I do exactly this: http://jpapa.me/spaps
So you ask "why Breeze?" ... because I strongly recommend it for building a SPA.
Thanks for asking and good luck !
Thanks for asking the question.
John, as author of HT, has offered an answer. I, as a principal of the Breeze project, am inclined to agree with him :)
HotTowel generates a foundation for you to build upon. It is not the building itself.
It is a foundation intended for a specific kind of application, a CRUD application based on a specific set of cooperating JavaScript and ASP.NET technologies. Breeze is a contributor ... but not the only one. Knockout, with its MVVM design and 2-way data binding, is particularly well-suited to the data-entry tasks typical of CRUD apps.
Of course there are other kinds of SPAs. There's an important class of apps that mostly present information and accept little user input. Such apps don't benefit as much from data binding and the people who write them can get pretty hostile about data binding in general and KO in particular.
My point is that HT targets a particular class of application ... one that happens to be immensely successful at least when measured by sustained popularity. It delivers the goods for people who build those apps. It may not be the right starting place for other kinds of apps.
It is true that the easy road to Breeze runs through Web API, EF, and a relational database. Take those away, and you may writing more code on the server (and a little more on the client). That may be the perfect trade-off for you.
The authors of Breeze would like to make that path easier. I don't think BreezeJS makes it harder. I don't understand your statement "Breeze becomes very difficult to use." Have you tried it?
Your client can communicate with any HTTP resource in any manner you chose. It is pretty easy to use existing Web API controllers (albeit easier with Breeze Web API controllers). You can use amplify.js if you prefer (btw, you can tell Breeze to make AJAX calls with amplify). You don't even have to use the Breeze EntityManager to query and save data if you don't want to.
The rest of BreezeJS may still have value for you. There remains plenty of work to do after you've figured out how you'll retrieve and store data and whether you prefer Entity-ChangeSet style or Command/Query style.
You'll have to find answers to these questions:
How will you shape the raw JSON data into bindable objects?
How will you hold on to these objects and share them across multiple screens without making redundant round-trips to the server?
How will you navigate from one object to a related object as you do when binding an Address to a combobox of StatesAndProvinces?
How will you track changes?
How will you validate them?
How will you store some or all of the data in local storage when the app "tombstones"?
Breeze can help with these chores even if you don't want it to query and save for you.
And if you're answer remains "I'll do all of that myself, thank you" ... well, removing Breeze from your HotTowel project is as easy as:
Uninstall-Package breeze.webapi

How to generate URLs to link back to objects?

I'm trying to build some RESTful services using spray. I've figured out how to build the directives I need. But the issue I'm having is how to reliable generate URLs back to the "resources" I'm working with. Note I use the term "resources" here as it is used for RESTful APIs (i.e. the server side objects one refers to through the API).
I've looked through the documentation and I haven't found any reference for this except mention of "Resources" in the Java sense (i.e. data files in the classpath).
For sure I can build a directive that maps "/items/127" to a resource on the server side. But what I don't see how to do (at least in a safe and automatic way) in Spray is how to generate such a URL given the server-side resource. I'm looking for something similar to url_for from the Flask framework.
For now, I'm writing functions to do this. But, of course, they are fragile because they aren't DRY (i.e. they don't use any knowledge of Spray routing in generating the URLS).
Am I missing something?
What you're asking for is known as reverse routing. As #iwein said, there's no direct support for reverse routing in Spray. You can confirm this from Matthias in this thread. There is an open ticket for this issue.
However, there is an approach, based on the PathMatcher that Marcel Mojzis open sourced which you can find here.
I have a need for this as well, but I'm going to get by with a "known pattern" approach until Spray (or akka-http) comes up with its own solution to this issue. Essentially, I have an object that knows how to generate the URL for certain patterns of things. Each pattern is a function and clients of the object have to ask for the url by one of the function names. Not ideal, but very simple and effective until akka-http provides a more generic solution.
I don't think that Spray has an equivalent of url_for. I don't think it would make sense in the context of Spray, because in Spray you're not annotating functions with urls that map to them, but you're creating routes that deserialize requests and eventually map them to functions.
As such there is no easy way to generate an example url from the name of a function.

How does plugin/plugin dependency work?

I've a very basic question about the practical operation of software plugin systems. I understand how a simple plugin design works, ie one where a plugin adds to a hosting application. Eg a plugin adds a new filter to a paint program. The host knows it has to call a method called filter which the plugin provides. In this case all plugins are independent.
My question relates to the case when one plugin can use the facilities in another plugin. For example there may be a plugin that provides the ability to plot data while another plugin generates data. If the data generator plugin has never seen the graphing plugin before I assume there is no way for it to know what methods to call in the graphing plugin. I presume that in these cases, the developer of the data generator plugin must have access to a description of the graphing plugin API either in the form of an abstract class or an interface. Is this how plugin dependency operates, ie plugins know explicitly about the Apis that other plugins might have?
I've just built such a plugin system and for plugins to be able to use other plugins I am including in the source code copies of the plugin interfaces each plugin needs to know about. The problem with this approach is that if a new plotting plugin comes along but with a different API, there is no way for the data generator plugin to use it without first being recompiled so that it is aware of the new API. This doesn't seem right to me.
I know this may seem to be a very simple question and have an obvious answer but I've spend hours searching the internet and I've not come across an explicit statement concerning this question.
If your "new plotting plugin" has a different API from the one your code knows about, there is no alternative but to make your code aware of this API.
If you are in control of all this, including the various plotting plugins, then you c/should specify a standard Plotting API that all plotting plugins need to implement/support. That is about the only way that you can have different providers (plugins) for some task.
A standard "language" is the way to ensure that you can use multiple implementors of an interface (providers of a service). It is also the way that you can have multiple users of the same interface (consumers of a service).
The need/wish for multiple providers of a task and for multiple consumers of a provider is probably what led to the creation of standards such as OAuth, and of protocols such as HTTP, SMTP and the like.

Resources