The first point in the Semantic Versioning Specification states that compatible software must declare a public API.
I'm wondering how gems establish this public API. It seems that it's typically done through the readme (see ActiveRecord, for example), which doesn't feel like it draws a strict boundary between the public API code and the rest. An example of a gem that does this better is the Twitter API, placing its public API code in an API directory, but even there the line is grey, as the public API's configure method is defined in twitter.rb, outside the API directory.
As a potential contributor to a gem that attempts to stick to semantic versioning (which is most of them, given we have tools like bundler), I'd like to know which methods are part of the public API, and which aren't. Maybe I have to look through more source code, but are there guidelines somewhere for clearly defining your public API?
There are some popular ways to define the public API. Which one you choose is mostly a matter of taste.
One way is documentation. You simply state in the documentation, which protocols are part of the public API, and what the contract of those protocols is. YARD even has predefined tags for this.
Another way is testing. I think Merb did this. The public API was described in its RSpec tests. The private parts were obviously also tested, but those tests lived in a different directory.
This is actually pretty cool, because it allows you to tie together code changes and semantic version changes: everytime you add a test to the public directory you need to bump the minor version. Everytime you delete or modify a test in the public directory you need to bump the major version.
Or the other way round: you are not allowed to change or delete tests during a minor revision.
Related
In my company, we're using Spring Boot to implement backend API and React to implement frontend including Web interface and Android/iOS apps.
Since our product is an Enterprise software, customers actually have to pay to get the latest backend API to deploy on their own servers. However, our mobile apps are regularly updated on the App Store. This leads to a situation where the mobile apps on end-users' devices may be the newer version while the backend API on the customer's machine is the older one. We plan to support up to 3 minor version backward, meaning FE 5.4 will support up to backend 5.2.
The backend does have an endpoint to return the current version number. However, I'm a bit clueless as to how our frontend implementation can maintain backward compatibility with older API versions as we add new features and may introduce breaking changes in backend API.
I completely understand there might not any beautiful solutions for this problem. I'm hoping if you've gone through this pain, you can share your experiences about what you've tried, the final approach that you took and the potential pitfalls to look out for.
I'm sure myself and other people who's running into this issue would be really grateful :).
Your solution will be similar to any frontend solution that uses Feature Toggle but I can already imagine that it will not be pretty.
Basically inside your code you'll have a lot of if/else statements or some form of wrapper that does the same underneath for every piece of UI/logic/functionality that is a breaking change on version upgrade.
I'd suggest that for every layers that you have (UI, logic, API call) you should start to have switches based on version returned by backend. You'll end up with a lot of redundant looking codes and a lot of codes that looks like this. (if you support only two versions. Use switch if you have more versions)
render() {
{version === "1.0.0" ? <VersionA /> : <VersionB/>}
}
You can however, write a utility method that wraps and returns different components based on versions. By doing that you can more easily remove components that you no longer need to support in the future.
const versionSwitcher = (version, ...Components) => {
switch (version) {
case "1.0.0":
return Components[0];
case "1.1.0":
return Components[1];
}
}
This of course, increases complexity throughout all layers but given your case I can't see it being simple. A good thing to do is to try to keep your own viewModel and never pass response from API directly into component. That reduces the coupling between API and your components and will make this a little easier.
I'm looking for recommendations on how to best share code between multiple Visual Studio projects. I'm struggling with a fundamental topic and trying to get some ideas to get over it.
My solution has:
Several web app projects
Several standalone process projects, eg Windows Services and/or console apps and/or Azure WebJobs
An example of functionality which is common to all projects is the need to call some common web service, or the need to read and write from Amazon S3, for example.
Where I struggle is this: Obviously the code that implements the common functionality should be broken out on its own, for example in a separate class library project. To talk to S3 for example, the code needs to know my Amazon credentials, S3 endpoints, etc. - all these things would normally be stored in app configuration files. But I don't like the idea of putting config files in class library projects because it binds a particular implementation to them. But in order to not do that, I have to pass in this information from the calling project. So for example the web app's web.config and the console app's app.config files contain this connection information. When calling the S3 code, I would assumingly pass this config info into the shared code.
However, this seems yucky* to me and I'm not sure why. It still feels to me like I'm "binding" the S3 code (for example) to a particular config method, if that makes sense. I'm not sure if my feeling is a mis-formed bias.
*For example, I may have an arbitrary amount of configuration data that would have to be passed in:
Connection strings
Credentials for web services
API endpoints
Arbitrary data from my app's config settings (which some of the callers will need, but others won't, so lots of times the data will just be useless yet I have to do the work of passing something in)
So every time I added a config variable in my main app, I'd have to modify the constructor of the common code. Things would be in constant motion.
Can you give me suggestions on this?
I like to use Configuration objects as parameters, that way the signature never changes, even if you add/remove properties. For instance....
public class AmazonConfigSettings {
public string AWSkey { get; set; }
public string ApiEndpoint { get; set; }
......
}
Your signature could then always look like:
public MySharedClass(AmazonConfigSettings config) { .... }
Even if (when) Amazon overhauls their webservice settings completely.
What is the best approach to version WebAPIs?
I am building an API from scratch and I would like to ensure that it will version gracefully in the future. I am envisioning something like mysite.com/api/v2/...
One approach I see is to create a separate project (web app) for each version of API. But perhaps there are better ways to do it?
Thank you for your ideas.
Including version number in the URL is the standard approach as I explained in this post (I do not repeat the content): Implementing versioning a RESTful API with WCF or ASP.Net Web Api
You do not need to create a completely new project although you can. The problem that you will be facing with a single project is that there will be collision of names:
/api/v1.0/Car/123
and
/api/v2.0/Car/123
both will point to CarController while you can have only one of those. The solution would be to implement your own IHttpControllerSelector and register with the DependencyResolver. This implementation will look at the version number and perhaps find the type based on the namespace.
UPDATE
I do not intend to start a REST controversy here. But as #DarrelMiller points out, here is an older discussion on the same subject discouraging my suggested approach:
How to version REST URIs
I personally think URL versioning is the way to go.
You will need to create your own implementation of IHttpControllerSelector. The best way is to base this implementation on Microsoft's IHttpControllerSelector. Then you can decide in your IHttpControllerSelectorif you want to version by URL or by content-type.
The most basic implementation directly implements IHttpControllerSelector and just implements the SelectController method but performance reasons it is better to implement some caching around it.
For finding the Controller you simple the IHttpControllerTypeResolver instance you can get using HttpConfiguration.Services.
I've used something like this: http://damsteen.nl/blog/implementing-versioning-in-asp.net-web-api. Also put some code on Github: https://github.com/Sebazzz/SDammann.WebApi.Versioning.
I have a bunch of notes in Evernote which I would like to access in a Rubyish way (instead of only using the web interface). I thought I'd use this gem (https://github.com/cgs/evernote), which is "...a high level wrapper around Evernote's Thrift-generated ruby code. It bundles up Evernote's thrift-generated code and creates some simple wrapper classes."
I got a developer key, and the sample code here (https://github.com/cgs/evernote/blob/master/example.rb) worked, giving me the correct name for my sandbox notebook.
However, I don't understand what to do next. By "simple wrapper classes" I was expecting the Evernote::EDAM::Type::Notebook object to be some Enumerable object that I could use blocks to query. I dunno, something like
notebook.select {|note| note.tags == 'foo'}
But when I do the notebook.TAB TAB trick in IRB to look at available methods, there is nothing like that. The author of the gem refers users to Evernote API at http://www.evernote.com/about/developer/api/ref/ , and I can't make heads or tails of the thing. Am I out of luck until I fully understand what things like THRIFT means, or is there a simple listing of methods somewhere that I'm failing to look?
You shouldn't have to learn anything about Thrift. The data model wrapper classes (Note, Notebook, Tag, etc) are basically dumb structs; the methods to exercise them are on the endpoint classes, UserStore and NoteStore. For example, to get a list of Notebooks, you'd call NoteStore.listNotebooks. You can see some examples in the SDK under ruby/sample.
I've run into this issue recently, to use Ruby accessing the Evernote API. And here is the list which may help:
Official Ruby Demo
Evernote Developer Guide
Evernote API: All declarations
ENML
And I wrote a demo to make it more specific and straight.
Evernote API Ruby demo
I have downloaded a coverflow sample from the link
http://www.macresearch.org/cocoa-tutorial-image-kit-cover-flow-and-quicklook-doing-things-we-shouldnt-are-too-fun-resist.
I need open flow effect but I dont need miror effect of images.Is it possible to do it.Is there any API available in IKImageFlowView class.
Any help would be appreciated.
There is no API available for IKImageFlowView. It is a private class. That's why the blog post is titled "doing things we shouldn't." If you look at the project in the blog post, you will find a reverse-engineered IKImageFlowView.h. That's as much information as is available. You can use class-dump as noted in the blog post and see if you can find the IKImageFlowViewDelegate protocol if there is one (this class appears to take a delegate). That might allow you to configure it.
Note that Apple may change this class at any time.
You are probably better off using a third-party implementation like MBCoverFlowView or OpenFlow.