REST – The uShip Blog https://ushipblogsubd.wpengine.com Fri, 14 Oct 2022 20:18:46 +0000 en-US hourly 1 https://wordpress.org/?v=6.8.2 Does your REST API need an SDK? https://ushipblogsubd.wpengine.com/shipping-code/does-your-rest-api-need-an-sdk/ https://ushipblogsubd.wpengine.com/shipping-code/does-your-rest-api-need-an-sdk/#comments Thu, 18 Feb 2016 08:41:02 +0000 https://ushipblogsubd.wpengine.com/?p=4273 Introduction When integrating with a platform that offers a REST API, a developer sometimes has the option of downloading the client library in their language of choice, or writing HTTP code themselves to integrate with the API directly. You as an API provider should decide early on if you wish to offer SDKs to your... Read More

The post Does your REST API need an SDK? appeared first on The uShip Blog.

]]>
Introduction

When integrating with a platform that offers a REST API, a developer sometimes has the option of downloading the client library in their language of choice, or writing HTTP code themselves to integrate with the API directly. You as an API provider should decide early on if you wish to offer SDKs to your customers.

REST, SOAP, and WSDLs

REST in its simplicity has generally been considered less of a barrier to entry than more cumbersome SOAP APIs, despite not having the assistance of a WSDL to aid in generating client code easily. One of the things that made REST simple was the flexibility in its design. As a consequence, for a long time there was not a common, standardized way to describe a REST API’s interface. Swagger has recently come to fill this void, even offering a tool to autogenerate client SDKs via swagger-codegen. However, these tools for REST APIs are fairly new. Hand-written SDKs have been offered by quite a few API providers for the past several years, their necessity varying from provider to provider.

Case study: Braintree

Braintree, a platform that makes it easy for your application to accept various forms of payment, does not offer a public REST API. Instead, they choose to deliver their platform through language-specific client libraries that they maintain. They have a wonderful write-up here. Things to note in the case of Braintree:

  • Their API is their business, and they need to do anything they can to make sure that clients can integrate easily.
  • They are in a space (payment processing) where security and application correctness are incredibly important.

For Braintree, SDKs make sense. They allow clients to integrate quickly with a complicated workflow and can abstract away things that the client doesn’t necessarily care about. For your API, it might also make sense to have an SDK if your API has non-trivial functionality such as a complicated authorization scheme, binary data serialization, request signing, etc. This is especially true if your clients do not need to customize any of this functionality.

Case study: uShip

We at uShip started our API platform with SOAP (which, to my surprise, looks like it is still in use here o_O). Eventually, we moved to a more RESTful approach, especially in anticipation of releasing native mobile apps. Things to note about our case:

  • Our mobile and web platforms are our business. A majority of external API integrations simply push customers to our platform.
  • Most integrations by third parties are limited in scope (targeted to a small subset of the markets we support) and therefore consume a very limited amount of easy to consume REST APIs, which makes the need for an SDK not as important.

For uShip, SDKs do not make sense as a necessity yet. Integration against our API via the REST interface is quick and easy. For your API, an SDK does not make sense as a necessity if your SDK does not offer much beyond simple HTTP bindings, especially if you don’t have the developer resources to maintain the SDKs in terms of bug fixes, new features, and availability on many platforms. This isn’t to say that you should not offer an SDK. Some form of example client interaction is always useful to a prospective integrator. Even if this means that I as a developer only end up using your DTOs (which are easy enough to automatically generate).

Automatically generating SDKs

When writing an SDK by hand, most of your code usually ends up looking like the following:

public class NounClient
{
  private final String BASE_PATH = "https://api.example.com";
  private HttpClient _httpClient;
  
  public NounClient() {
    _httpClient = new HttpClient();
  }
  
  public Noun getNouns(string filter) {
    String resourcePath = "/nouns?filter=" + filter;
    HttpRequest request = new HttpRequest(BASE_PATH + path)
    HttpResponse response = _httpClient.Execute(request);
    return response.Content.Deserialize(Noun.class);
  }
}

The resource names will be different, and you might add a couple of helper classes that allow a client to interact with your API easier, but a lot will look like copy-paste. With hand-written SDKs, there is a huge amount of boilerplate code that adds very little value for consumers, which means lots of wasted development efforts on your part. As developers we know things like this can and should be automated.

With the aforementioned tool swagger-codegen, it is possible to take a swagger spec and automatically generate client libraries. The default template can get you pretty far (especially if you lack resources in a particular programming language), but the real power comes in being able to write custom templates to generate the boilerplate. This allows you to spend your time designing an SDK instead of dealing with boring HTTP code. For the longest time we didn’t have any sort of SDK, but having something autogenerated lets us dip our toes in the water. Now we have something that internal (or even external) projects can use to quickly build a prototype application.

Conclusion

Whether you want to offer an SDK depends on the experience you would like your client to have, and that ultimately comes from how your API was designed, but no SDK will make a poorly designed API easy-to-use. A chatty API could lead to chatty code, or at the very least high latency between calls. Covering up a bad API with an SDK will inherently make the client complicated and could lead to possible bugs. Regardless of the existence of an SDK, good documentation with pertinent examples of common integration patterns is a must.

[amp-cta id=’8486′]

The post Does your REST API need an SDK? appeared first on The uShip Blog.

]]>
https://ushipblogsubd.wpengine.com/shipping-code/does-your-rest-api-need-an-sdk/feed/ 5
From Zero To Swagger: Retrofitting an Existing REST API to an API Specification Using Swagger https://ushipblogsubd.wpengine.com/shipping-code/from-zero-to-swagger-retrofitting-an-existing-rest-api-to-an-api-specification-using-swagger/ https://ushipblogsubd.wpengine.com/shipping-code/from-zero-to-swagger-retrofitting-an-existing-rest-api-to-an-api-specification-using-swagger/#respond Thu, 12 Nov 2015 08:15:13 +0000 https://ushipblogsubd.wpengine.com/?p=4218 Introduction Here at uShip, our web services have gone through quite a change over the last few years. We have gone from SOAP based services to a RESTful API. Recently we dipped our toes into Swagger, an API specification framework, to provide more value to our developers and external partners. Why Swagger? We originally started... Read More

The post From Zero To Swagger: Retrofitting an Existing REST API to an API Specification Using Swagger appeared first on The uShip Blog.

]]>
Introduction

Here at uShip, our web services have gone through quite a change over the last few years. We have gone from SOAP based services to a RESTful API. Recently we dipped our toes into Swagger, an API specification framework, to provide more value to our developers and external partners.

Why Swagger?

We originally started to experiment with Swagger because we heard great things about swagger codegen, a tool that automatically generates client libraries from a Swagger specification. We had an internal SDK for consuming our own APIs that we built by hand in C#. Every time someone had to consume an internal API, someone had to add to this SDK and go through the code review process as we do with every other line of code. After a while, we started to notice that the code that was manually written conformed to a pattern that could easily be reproduced by a machine. Combine that with various other tools that integrate with Swagger specifications, and we just had to try it out!

How we did it

Because we have more than a handful of existing APIs, we thought that manually writing a Swagger specification by hand would not be worth our time. Luckily, we found Swashbuckle, a library that integrates with our .NET Web API implementation to automatically discover APIs and generate a spec. After getting the kinks out of that integration, we had a valid spec and were able to generate usable SDKs in a couple of languages. We were hooked!

What we learned

Going into this, we simply expected to make use of the tools that Swagger provides. It turns out that we actually learned quite a bit about our API and its implementation.

We weren’t consistent

  • We try to reuse as many objects in our API as possible. Because we’re in the shipping industry, one of our most common reusable inputs is an address that looks like the following:
    {
    "postalCode": "78731",
    "country": "US",
    "type": "Residence"
    }
    

    One of our resources was actually using the following for input:

    {
    "postalCode": "78731",
    "country": "US",
    "type": {
    "value": "Residence",
    "label": "Residence"
    }
    }
    

    This object does indeed exist in our API, but should have only been used for outputs. By the time we found this discrepancy, we already had too many clients consuming the resource to be able to change it.

    We have since added an integration test in our codebase that scans all APIs and verifies that only GETs and PUTs can use the output address.

  • We try very hard to make sure that our APIs and their implementations follow internal documented standards. What we failed to do was enforce all those standards via some form of automated testing. Here is an example:
    using System.Web.Http;
    
    namespace uShip.Api.Controllers
    {
    public class EstimatesController : ApiController
    {
    
    }
    }
    

    Above is our controller that receives requests from our POST /v2/estimate resource, an API that allows you to calculate a rough estimate of how much it would cost to ship your anything from anywhere to anywhere. We try to follow the convention that controllers should be named directly after their resource. We slipped up in this case, and named the controller EstimatesController instead of EstimateController.

    What does this incredibly minor inconsistency have to do with Swagger? By default, Swashbuckle will use controller names to generate a set of classes for a client library. Someone wanting to consume the POST /v2/estimate resource through the client library would have to do the following:

    var api = new EstimatesApi();
    api.EstimatesPost(/*POST body*/);
    

    This could confuse the client, especially in a dynamic language.

    Again, we have added an integration test that scans all APIs and verifies that routes match controller names. Since we don’t have to worry about breaking clients when we rename controllers, we were able to make these changes right away.

  • We never thought to follow a pattern when naming the server-side C# classes that are used for deserializing request bodies. If we had a resource called POST /v2/Nouns, we could have any of the following class names:
    • NounInput
    • NounModel
    • NounInputModel
    • PostNounModel
    • NounCreationRequest (not even kidding)
    • ReubenSandwichModel (alright, kidding a little bit on this one)

    The above is not only a nightmare for discoverability when investigating an existing API, it also makes for a terrible situation for Swashbuckle. Swashbuckle reuses the class names for the models it will use in the client libraries. While autocompletion in the IDE kind of hides this problem, it’s still not very nice for the client to deal with.

    We haven’t written an integration test for this particular issue quite yet, but writing such a test or anything like it is trivial to do with Web API.

We should have started with an API specification

We wouldn’t have had any (or at least as many) of the mistakes as we did above had we started with some form of an API specification. Having one source of truth for our API would have saved us so much headache when compared to our collection of API “definitions” scattered throughout our issue tracker tickets, acceptance tests, lacking documentation, and API developer knowledge.
When we started creating our API, API definition languages weren’t very feature complete. Now, with Swagger being the official API description language of the Open API Initiative, we all have the tools necessary to do things right from the get-go.

Caveat

Even after we created something amazing, we realized that we didn’t create an API specification. What we created was a way for our API to produce a convenient byproduct. Any “specification” we automatically generated would have just been a self-fulfilling prophecy. APIs should be built to spec; specs should not be built from APIs (at least in the long term). We have toyed with the idea of taking more of a design-first approach to building APIs, especially as we start building out APIs for our new microservices. But currently, we are content with what automatically-generated, retrofitted Swagger has given us. You should give it a try!

[amp-cta id=’8486′]

The post From Zero To Swagger: Retrofitting an Existing REST API to an API Specification Using Swagger appeared first on The uShip Blog.

]]>
https://ushipblogsubd.wpengine.com/shipping-code/from-zero-to-swagger-retrofitting-an-existing-rest-api-to-an-api-specification-using-swagger/feed/ 0
Implementing API Errors with Web API and FluentValidation https://ushipblogsubd.wpengine.com/shipping-code/implementing-api-errors-web-api-fluentvalidation/ https://ushipblogsubd.wpengine.com/shipping-code/implementing-api-errors-web-api-fluentvalidation/#comments Thu, 10 Sep 2015 08:37:37 +0000 https://ushipblogsubd.wpengine.com/?p=4172 In a previous article, we talked about how APIs should return RESTful error responses so that API clients can act on them. There are plenty of articles like this one that talk about how to actually integrate the FluentValidation framework into the Web API pipeline, so we won’t go into the plumbing details. Below is... Read More

The post Implementing API Errors with Web API and FluentValidation appeared first on The uShip Blog.

]]>
In a previous article, we talked about how APIs should return RESTful error responses so that API clients can act on them. There are plenty of articles like this one that talk about how to actually integrate the FluentValidation framework into the Web API pipeline, so we won’t go into the plumbing details. Below is a simple implementation of the RESTful API response model using these tools.

Validation Options

There are numerous options one has when choosing how to validate input using Web API. A classic option commonly used in Web API tutorials is using attributes for model validation. We started off going this route, but ran into a couple of issues:

  • Some of our validation rules depended on two adjacent properties. We found ourselves constantly overriding the default attribute validation behavior to account for this.
  • In many cases, our input models had shared nested models, but we needed different validation for the nested properties. Adding an attribute to the shared nested model did not allow it to be reused with different validation rules.

FluentValidation is a very flexible validation framework and is perfect for our needs.

WithState

FluentValidation provides an extension method when building validation rules called WithState. This method allows you to add any context you wish to the current rule. Whatever object you add to this context will be available to you when the rule fails. Let’s see it in action.

First, define an object that will hold the data we will need when validation fails:
[cc lang=”csharp”]
public class ErrorState
{
public ErrorCode ErrorCode { get; set; }
public string DocumentationPath { get; set; }
public string DeveloperMessageTemplate { get; set; }
public string UserMessage { get; set; }
}

public enum ErrorCode
{
None = 0,
Required = 10271992,
TooShort = 11051992
}
[/cc]

Next, define the validator that takes advantage of the WithState method and uses the aforementioned ErrorState object to encapsulate the type of validation failure:
[cc lang=”csharp” escaped=”true”]
public class UserInputModelValidator : AbstractValidator<UserInputModel>
{
public UserInputModelValidator()
{
RuleFor(x => x.Username)
.Must(x => x.Length >= 4)
.When(x => x.Username != null)
.WithState(x => new ErrorState
{
ErrorCode = ErrorCode.TooShort,
DeveloperMessageTemplate = “{0} must be at least 4 characters”,
DocumentationPath = “/Usernames”,
UserMessage = “Please enter a username with at least 4 characters”
});

RuleFor(x => x.Address.ZipCode)
.Must(x => x != null)
.When(x => x.Address != null)
.WithState(x => new ErrorState
{
ErrorCode = ErrorCode.Required,
DeveloperMessageTemplate = “{0} is required”,
DocumentationPath = “/Addresses”,
UserMessage = “Please enter a Zip Code”
});
}
}
[/cc]

Returning a RESTful Response

Before we can return the validation’s result to the client, we must first map it over to our RESTful API error structure.

The following objects are code representations of the JSON that we will send back to the client:
[cc lang=”csharp”]
public class ErrorsModel
{
public IEnumerable Errors { get; set; }
}

public class ErrorModel
{
public ErrorCode ErrorCode { get; set; }
public string Field { get; set; }
public string DeveloperMessage { get; set; }
public string Documentation { get; set; }
public string UserMessage { get; set; }
}
[/cc]
Notice how ErrorModel is very similar to ErrorState. ErrorsModel is our contract to the outside world. No matter how our validation implementation changes, this class must stay the same. Conversely, ErrorState is free to change as you improve your validation layer. You can add convenience methods, new enums, etc. without worrying about changing the JSON response to the client.

Once we run our validator, it is time for Web API to handle converting the result to something a client can consume. Below is code that can be placed in an ActionFilter:
[cc lang=”csharp” escaped=”true”]
private void ThrowFormattedApiResponse(ValidationResult validationResult)
{
var errorsModel = new ErrorsModel();

var formattedErrors = validationResult.Errors.Select(x =>
{
var errorModel = new ErrorModel();
var errorState = x.CustomState as ErrorState;
if (errorState != null)
{
errorModel.ErrorCode = errorState.ErrorCode;
errorModel.Field = x.PropertyName;
errorModel.Documentation = “https://developer.example.com/docs” + errorState.DocumentationPath;
errorModel.DeveloperMessage = string.Format(errorState.DeveloperMessageTemplate, x.PropertyName);

// Can be replaced by translating a localization key instead
// of just mapping over a hardcoded message
errorModel.UserMessage = errorState.UserMessage;
}
return errorModel;
});
errorsModel.Errors = formattedErrors;

var responseMessage = new HttpResponseMessage(HttpStatusCode.BadRequest)
{
Content = new StringContent(JsonConvert.SerializeObject(errorsModel, Formatting.Indented))
};
throw new HttpResponseException(responseMessage);
}
[/cc]
Our filter is doing the following:

  • Mapping our ErrorState object inline to the ErrorModel contract that we will be serializing
  • Creating an HTTP response object with the serialized data, which is then sent to the client by wrapping the response in and throwing an HttpResponseException

Now the client is ready to handle the nicely-structured API response.

Conclusion

FluentValidation is a powerful validation framework whose WithState method is a great entry point for custom logic including generating RESTful error responses. If you would like to see a full implementation, you can clone this GitHub repo. Keep in mind that this is a rough example and will most likely need to be modified to meet your exact needs and current infrastructure.

[amp-cta id=’8486′]

The post Implementing API Errors with Web API and FluentValidation appeared first on The uShip Blog.

]]>
https://ushipblogsubd.wpengine.com/shipping-code/implementing-api-errors-web-api-fluentvalidation/feed/ 1
Actionable RESTful API Errors https://ushipblogsubd.wpengine.com/shipping-code/actionable-restful-api-errors/ https://ushipblogsubd.wpengine.com/shipping-code/actionable-restful-api-errors/#comments Thu, 27 Aug 2015 09:32:00 +0000 https://ushipblogsubd.wpengine.com/?p=4164 No matter how hard your API clients try, they will eventually get back errors from your API. apigee has an excellent blog post describing the reasons why detailed error messages are incredibly important for API client developers when starting to consume your API. When designed and used appropriately, these errors can be immensely useful to... Read More

The post Actionable RESTful API Errors appeared first on The uShip Blog.

]]>
No matter how hard your API clients try, they will eventually get back errors from your API. apigee has an excellent blog post describing the reasons why detailed error messages are incredibly important for API client developers when starting to consume your API. When designed and used appropriately, these errors can be immensely useful to the end users of API client applications.

The Simplest Errors: String Error Messages

[cc lang=”javascript”]
HTTP/1.1 400 Bad Request
Content-Type: application/json

{
“errors”: [
“Zip Code is required”,
“Username must be at least 4 characters”
]
}
[/cc]

Above is a common response for errors from an API. Although it is common, it is not an ideal response. In the case of form validation, clients may not be able to handle every error case themselves. To handle additional errors, they can catch 400 error responses from the API and display the provided message.

simple errors

Pictured is a sample Android application consuming these simple errors. While this method of displaying errors works, it has its downsides:

  • The wording of the user facing messages have to be chosen carefully to point the user in the right direction.
  • On a long form, users will also have to scroll back and forth between reading the error messages and correcting their mistakes.

More Advanced Errors: Actionable Error Objects

[cc lang=”javascript”]
HTTP/1.1 400 Bad Request
Content-Type: application/json

{
“errors”: [
{
“errorCode”: 10271992,
“field”: “Address.ZipCode”,
“developerMessage”: “Address.ZipCode is required”,
“documentation”: “https://developer.example.com/docs/Addresses”,
“userMessage”: “Please enter a Zip Code”,
},
{
“errorCode”: 11051992,
“field”: “Username”,
“developerMessage”: “Username must be at least 4 characters”,
“documentation”: “https://developer.example.com/docs/Usernames”,
“userMessage”: “Please enter a username with at least 4 characters”,
}
]
}
[/cc]
Above is a much more detailed error response from an API. This JSON response format is ideal, since it gives the developer the power to do something with the errors.
Here’s a breakdown of a possible structure for actionable API errors:

  • ErrorCode: A unique code per type of error (required, too long, profanity filter, etc.).
  • Field: The field in the HTTP request that caused the error to be triggered. The could be a property on a JSON object for a POST request or a query parameter in a GET request. API clients would use this to bind back to their application.
  • DeveloperMessage: A plain English message that describes what the error is, aimed to help the developer fix errors in their consumption of the API.
  • Documentation: If applicable, this could return link to the API documentation that describes where the particular validation rule is defined. This could be to an index of errors, or to a section on the API resource being consumed.
  • UserMessage: A localized message that describes what the error is, to be presented in a UI aimed to help the end user of the application. If a client wanted to do so, they could take advantage of the ErrorCode and Field properties of an error to produce a custom error message that would override the message provided by the API.

Because the context of the source of the error is returned from the API, the API client can catch those 400 error responses and bind them to their UI to tell the user which fields specifically need to be modified.

actionable errors

In this example, the client wanted to provide a very specific message as to why a Zip Code is required to register on the application. To accomplish this, the client can parse the response from the API as shown above to look for an error with the “required” error code (in our case, 10271992) and an Address.ZipCode field. The client still has the option of falling back to the “userMessage” field from the API, as in the username validation case above.

Implementation

The pattern outlined by the example JSON response in the previous section could easily be implemented in many languages and API frameworks. In a follow up post, we will walk through a sample implementation in C# with ASP.NET Web API and FluentValidation.

Conclusion

Your API’s error responses should be designed alongside the rest of your resources. While returning simple string messages is a good starting point, you should always strive for complete error responses to make life easier for your API clients. Following these error response best practices both on the server and client side will ensure that even if the HTTP status code of an API call is not 200, your client will be OK.

The original post can be found on my personal site.

The post Actionable RESTful API Errors appeared first on The uShip Blog.

]]>
https://ushipblogsubd.wpengine.com/shipping-code/actionable-restful-api-errors/feed/ 2