We have REST-API based on ASP.NET WebApi. And we distribute bia nuget .net client library to communicate with our API.
WebApi controllers and client library shares client models.
If I add some new optional field to model - it's ok, but when in some new release we accidentally add new enum value on API, previous version of client will thrown exception if it receives new enum value.
So, it there any way to check backward compatibility of API and client and prevent breaking changes?
In this particular case: don't use enum in client libraries. This situation will happen every time when you need to extend this enum. I suppose you don't want to make a new version of API for each such change. Inside your client you should accept string values and then try to parse it. If it's parsed - OK, if it's not - set YourEnum.None.
In general: to prevent breaking changes you should create integration tests and run them on your CI server. If you add a new rule in api - existing integration tests shouldn't fail. At the same time there is no 100% guarantee. It depends on how you are meticulous while writing integration tests. The same story as for unit testing actually.
when in some new release we accidentally add new enum value on API, previous version of client will thrown exception if it receives new enum value.
Based on #mtkachenko's answer: Write integration tests where all supported versions of your client (also 3rd party clients, if any) are tested against the release candidate (or dev/staging/QA environment) of your API.
If the tests fail with any of these client versions, then your API change is incompatible.
Plan for extension - e.g. in JSON, prefer objects over plain strings/numbers, so you can add more fields in the future.
Also document expected future extensions, so developers are aware that e.g.
a particular field may get additional values in a future API version, and unknown values can be treated e.g. like the existing value XY.
a particular array field which today always has one element may in the future have multiple elements.
add new enum value
Zalando suggests to never extend enums that are used in responses:
https://opensource.zalando.com/restful-api-guidelines/#107
You may also find more useful information there, I think their document contains lots of good principles and ideas:
https://opensource.zalando.com/restful-api-guidelines/#general-guidelines
https://opensource.zalando.com/restful-api-guidelines/#compatibility
https://opensource.zalando.com/restful-api-guidelines/#deprecation
This looks like a typical use case for REST API versioning.
You can will need to support different versions in API and then have your client specify which version it is requesting.
Different mode of versioning are:
URL Versioning
api.example.com/v1
Versioning using header if you want to keep a single URL for a resource
Accept:Version: v1
Refer microsoft api versioning guideline here.
The library is pretty well documented.
Related
I have a web api that others are using, and one of our developers changed the name of the action method or method parameter. Now the client has a problem. Is there any solution that, before deploying to the production server, check whether there have been changes in the existing public api (not adding new api)?
I would highly recommend creating a Swagger OpenAPI Specification for your API if you're going to be sharing your API with other teams. A Swagger definition is a specification that describes how your API looks like in terms of actions, expected input, output, etcetera. You can use such a specification as a contract between the producer and all consumers of your API.
Then, you can use tools like Swagger CodeGen to generate clients and server implementations, as a guarantee that an implementation conforms to the contract. In your case, this would prevent a developer from breaking the API (unless they change the contract as well).
If you want to collaborate, I recommend placing (a copy of) your Swagger definitions in a separate GIT repo (e.g. my-awesome-contracts), give all the teams access to this repo and make any changes through pull requests. This serves two purposes:
It gives all the consumers of your API an early notice on any changes
you're planning to make.
It allows any consumers to actually give feedback on the proposed changes.
I have a Windows UWP client application that needs to call a REST API hosted by my ASP.NET service. To generate my client proxy I use the following Visual Studio option...
Right click project -> Add -> REST API Client...
I provide the URL of the swagger endpoint and it generates the expected client code. But the downside is it generates all the classes even though in my case I have a shared class library that has all the server side classes defined. This is a pain because the generated classes do not respect the inheritance of my class hierarchy and flattens everything into non-inherited classes.
Is it possible to get AutoRest to reuse an existing .NET library for classes instead of always generating new classes? This was an option when I used the WCF client proxy generator.
It seems like Add REST API client doesn't have advanced setting for reusing. But Add REST API client has two ways for loading metadata file, swagger URL and existing metadata file. By testing on my site, it should be able to update an existing metadata file and to remove or adjust the nodes that you don't want be generated. And then load the updated existing metadata when adding REST API client.
The classes generated may be determined by the metadata json file and the host value. You may also try to submit a request here to see if swagger team can keep the hierarchy when generating the meta file. Or you may need to manual create the proxy to reuse the libraries.
I think it would be fair to describe the "REST API Client" generation tool in Visual Studio as "spartan".
This answer may be too late to help you, or there may be reasons why you can't use a different tool, but in the hope of benefiting you and/or future readers I'll detail how I achieved generating a REST client in NSwagStudio which reuses my existing classes and enums. (NSwagStudio is free and open source, and I have no affiliation).
On the left hand pane, we select our input. Besides the expected Swagger feeds there are some interesting options such as "Web API via reflection" which "uses .NET reflection to analyze ASP.NET Web API or ASP.NET Core controllers" - this is the option I used but my screenshot shows the default Swagger input.
On the right hand pane, click "CSharp Client" and switch to the "CSharp Client" tab.
The magic bullet is to untick "Generate DTO types":
This will cause it to generate only the client, so you can reuse your existing DTOs.
You'll want to specify a namespace for the client, and optionally one or more namespaces which will be added to the generated C# file as using directives. For example, if you want your client to be in the namespace MyNamespace and your model classes are in SomeOtherNamespace you'd enter the following:
It's well worth having a play with the options. A few quick notes about some of the defaults and why I'm happy with them:
The HttpClient is injected and you control the lifecycle (which seems to me a good thing)
A BaseUrl property is defined. I haven't tested this yet but I'm hopeful from looking at the generated code that this will allow me to safely spin up multiple instances of the client class to talk to multiple servers which share the same API
The JsonSerializerSettings property is protected, but can be configured via the UpdateJsonSerializerSettings partial method
I've saved my settings from the File menu and added the .nswag file to source control, so that I can easily regenerate the client in future if necessary.
I am working on the asp.net web api where i have to return back objects in json. With respect to making a better approach and easy for (android/ios)mobile developer to consume these Web APIs and parse json objects, what is best approach for making these objects definitions remain shared amongst webapi project and mobile project, so that if we have to change any property then it can easily be reflected on both projects in a better way. It would be great if someone explains it in detail.
There is no such sync method as you are asking.
On your WebAPI server side you'll define the objects and then return them in your API methods. JSON serialization will be automatically handled by the framework, using your serialization engine of choice (i.e. JSON.NET). Remember that with WebAPI you don't decide the output format server side, you just return a response containing the object(s) and then the framework reads the HTTP HEADERS of the request to determine whether the client asked for JSON or XML and then returns what was asked.
The best thing you can do is define a clear API with nice conventions and keep it documented, and if you change anything have the documentation reflect the changes. Avoid making breaking changes, and if you really must, deprecate a property or an object for at least a couple of versions before removing it.
That's the way all public API work anyway.
I have an Interface and in some month I want to add parameters to that interface.
I read somewhere (link went missing) that when I use Datacontracts I can easily add Properties to the datacontract. The new Properties will just not be sent to the server on old clients.
In Theory I just have one Interface and my new and old client can use that Interface. Did I understand that correct?
But Now I am working with the validation Block from Microsoft. Does that break my "feature" of having interfaces which are easy to maintain?
What is a good way of managing different version of interfaces with the validation block?
It isn't really clear on whether you mean changes to methods on ServiceContracts, or changes to data in DataContracts, however, there is a degree of non-breaking change compatability in both:
For Service Contracts, From MSDN:
Adding service operations exposed by the service is a nonbreaking change because existing clients need not be concerned about those new operations.
With the proviso:
Adding operations to a duplex callback contract is a breaking change.
Adding new parameters at the end existing method signatures may work for client calls from old versions, but would result in a default value for the type being passed - e.g. null for reference types, zero for numeric types, etc. This might break things and require additional validation (e.g. DateTime.MinValue wouldn't gel well with a Sql DateTime column.
Similarly, for DataContracts, from MSDN
In most cases, adding or removing a data member is not a breaking change, unless you require strict schema validity (new instances validating against the old schema).
New datamember properties would be defaulted, and obsolete / removed properties would be ignored.
You can also rename members using the Name property on DataMembers.
VAB would be subject to the same rules - i.e. any validations on new fields would need to be aware of the defaults provided, which would imply you couldn't validate new fields.
Doing changes like this retroactively is not a good idea once you have clients connecting to your services - it pays to design an interface right first time, and then to have a versioning strategy going forward, where you can provide a facade for older clients to connect to an old interface, which then actually transforms the old format to the new one, and makes deliberate mapping and defaulting decisions about missing or obsolete data.
We're setting up a bunch of json web services in ASP.NET which is served as .ashx (custom handlers) files. An example would be:
/mobile/json.ashx
We'd like to implement some form of versioning as well as to not break apps which has not upgraded. So we led down this path:
/mobile/json.ashx?v=1.0
Now, of course we have have a switch statement in our custom handlers to manage the differences between api version but this doesn't sound like a very maintainable solution to me.
What are the best practises for this kind of set up and what options are available for version control?
Thanks
Placing the version in the query parameters (that is, after the ?) suggests to the user that each endpoint is individually versioned. I would avoid this.
If your web service is structured such that there are larger logical units that are being individually versioned, then I would go with something like this:
/api1/1.0/some/endpoint
/api1/1.1/some/endpoint
/api2/1.0/some/other/endpoint
/api2/2.0/some/other/endpoint
...
The version portion of the path comes directly after the thing which is being versioned. This suggests to the user that everything underneath /api1/1.1/ is version 1.1 of API 1 and everything underneath /api2/2.0/ is version 2.0 of API 2.
If someone entirely omits the version portion of the path, the latest version should be implied. So /api2/some/other/endpoint would map to, say, /api2/2.0/some/other/endpoint.
If you're using ASP.NET MVC, all of this can be accomplished very easy using route configuration in the RegisterRoutes method in Global.asax.cs. For example:
routes.MapRoute("api1/1.1", "api1/1.1/some/endpoint",
new { controller = "Api1_1_1", action = "SomeEndpoint" });
where you have a controller class Api1_1_1 with method SomeEndpoint.