My API allows users to filter a database table using query string params (ie. ?age=30&location=Philadelphia). These params are different for each database table. How can I express that in API Blueprint?
The API Blueprint spec says it supports the explode modifier. This RFC 6570 validator suggests the explode modifier could accomplish this via an object, ie.
/api{?filters*}
And passing
{ filters: { age: 30, location: 'Philadelphia' } }
(The validator linked above illustrates this a bit better)
Of course, I'm not sure how to express the above in API Blueprint. Is it possible?
Related
I have an app written with reason-react using apollo-client. I have defined some fragments on the frontend to basically reuse some field definitions. I'm setting up automated tests for a components that uses fragments, but I keep getting this warning saying I need to use the IntrospectionFragmentMatcher.
'You are using the simple (heuristic) fragment matcher, but your queries contain union or interface types. Apollo Client will not be able to accurately map fragments. To make this error go away, use the `IntrospectionFragmentMatcher` as described in the docs: https://www.apollographql.com/docs/react/advanced/fragments.html#fragment-matcher'
I've tried setting up the fragment matcher according to the docs. The codegen result returns no types:
{
"__schema": {
"types": []
}
}
When I queried my server and looked at the manual method recommended by apollo-client, I noticed it would also return no types.
Another strange thing is that when I don't use the fragment matcher, I get the mocked response back but I just get the warnings from apollo. If I do use it then the mocked response doesn't return correctly.
Why would I query the graphql api for fragments defined in my frontend code? Why would I only received these errors when running the tests & using mock data, but not when running my actual application?
As the error states, the default fragment matcher does not work on intersection or union types. You will need to use Apollo's IntrospectionFragmentMatcher. It works by asking the server (introspecting) for information about your schema types, and then providing that information for reference to the cache so that it can match the fields accurately. It's not querying the server for information about the fragments you are defining on the front end, it's asking for data about the GraphQL schema that must be defined on your back end so that it can properly relate the two. There is an example in the documentation, also more information here.
As for why your server is not returning any types, that is a separate issue that would require more info to debug. If you're using Apollo Server, doublecheck your schema to make sure all the necessary types are defined properly and that you are passing them into the server when it's initialized.
We often have use cases where we only want to update a subset fields on a resource. So if we have a resource Person:
type Person struct {
Age int
Name string
Otherfield string
}
Say the calling client only wants to update the Age field. How would an endpoint be normally set up to handle this?
I believe this should be done with a PATCH request, with only the fields being set as part of the payload, ie:
{
Age: 21
}
However, this won't work with proto3 because as far as I know there are no null fields, only default values. This won't work in many cases where the default value is valid.
Looking at Google own protobuf files (e.g. here), they use FieldMask for partial update.
FieldMask object is passed along with the request, and has the form (in JSON):
{
mask: "Person.Age"
}
This allows the client to tell the server which fields they wish to update, without counting on the partial message itself to figure this out.
I think this adds unnecessary complexity on (each!) client, but we couldn't find any other way to achieve partial updates with proto3.
You can see full documentation of FieldMask here.
Note that it can also be used to filter out responses if the client doesn't need the entire object.
I'm thinking about using Stormpath with it's Java API as a user storage.
Looks good, except that I can't search for users.
For example, I get this error:
Exception in thread "main" com.stormpath.sdk.resource.ResourceException: HTTP 400, Stormpath 2105 (http://docs.stormpath.com/errors/2105): Account ID is not a supported query property.
when I execute this query:
HashMap<String, Object> queryParams = Maps.newHashMap();
queryParams.put("ID", "4mPXXXXXXXXXX");
searchResult = application.getAccounts(queryParams);
Searching for a user by e-mail however works. I get the same error when I try to search a user by a login-token I stored in the customData property.
It looks like what I want to do is not possible as it looks like the only properties you can query are e-mail and username. But why would they provide this functionality if it didn't work. What am I missing?
There is an impedance mismatch between common relational database behaviors and those in a REST API. Querying by id, while common in relational databases, is not idiomatic behavior for REST APIs (or most HTTP-based web sites). The URL (href) is the canonical 'pointer' to a resource on the web. In other words, in REST APIs, the canonical identifier is the href. Any token inside an href (any internal 'id', special characters, whatever) should be opaque to REST clients and ignored by clients entirely. URLs are king in HTTP and REST.
That being the case, the Stormpath SDK tries to be true to RESTful best practices, so you can obtain any Stormpath resource by using the client.getResource method, which accepts an href and the type of object you expect that href to represent:
String href = "https://api.stormpath.com/v1/accounts/" + id;
Account account = client.getResource(href, Account.class);
That said, there's nothing wrong with wanting this to be more conveniently represented in the client API, for example, client.getAccount(String id) if you want to keep the notion of IDs. If so, please open a new feature request and we'll be very happy to consider it.
As for queryable Account properties, those are documented here. Stormpath will soon make data in Custom Data searchable as well. While Stormpath feature timelines are never announced, it is the company's highest engineering priority and it should be out soon.
One workaround that is helpful for some people is to store data they want to search in Account Fields that you don't use in your applications. For example, you could use the 'middle name' field to store, say, favorite color. This would only be temporary until custom data search is available. HTH!
I'd like to create servicestack api and use swagger for autoupdatable documentation. The problem is that I need this documentation to be i18n-azied, so the question is, is it possible to do in servicestack?
It's not natively supported but ServiceStack's SwaggerFeature does provide model and property filters that let you modify the returned swagger models, i.e. providing an opportunity to substitute the text in the returned models, e.g:
Plugins.Add(new SwaggerFeature {
ModelFilter = model => myLocalize(model),
ModelPropertyFilter = property => myLocalize(property)
});
Whilst it's not heavily used yet, ServiceStack's approach to localizing strings is to route text through to AppHost.ResolveLocalizedString() which can be overridden in your AppHost to change what string is returned.
I want to build a typical mvc app for CRUD of simple items, the api s should be RESTful. The catch here is, that i have a large pallete of items that needs to be initialized. On the server side those items are defined as java beans and the corresponding create form for the item is dynamically created from the field information(data type, validation constraints etc) harvested from the bean.
I am new to REST and just read up about how the urls should be nouns defining the resource and action specified by HTTP verb. In that perspective how to model something like
.../client/showForm?type=xyz from non RESTful way to RESTful one ?? My intention here is to tell the server to dynamically construct and send back a CREATE form for client of type xyz. The obvious problem with url i mentioned above is that it specifies action in the url which, from what i have read, makes it non RESTful.
When I think of REST, I think of resources. I think of data. In other words, I don't think of REST as being something that I would typically use to retrieve a form, which is a user interface component.
REST is an architectural style that is used to identify a resource on a server using a uniform resource identifier, or URI. Additionally, actions performed on those resources identified by the URI are determined based on the specific HTTP Method used in the request: GET, POST, PUT, DELETE, etc.
Thus, let's say you have a Client object. That client object might have the following properties:
Name
Location
AccountNumber
If I wanted to retrieve the data for a single client, I might use the following URI:
GET /client/xyz/ # xyx is the accountnumber used to identify the client.
I would use a GET method, since REST describes GET as being the method to use when retrieving data from the server.
The data could theoretically be returned in HTML, since REST is not a standard but more like a series of flexible guidelines; however, to really decouple my data from my user interface, I would choose to use something platform independent like JSON or XML to represent the data.
Next, when adding a client to the collection on the server, I would use the /client/ URI pattern, but I would use the HTTP Method POST, which is used when adding a resource to a collection on the server.
# Pass the data as JSON to the server and tell the server to add the client to the
# collection
POST /client/ {"accountnumber":"abc" , "Name" : "Jones" , "Location" : "Florida"}
If I were to modify an existing record on the server or replace it, I would most likely use the HTTP Method PUT, since REST guidelines say that PUT should be used if repeating the same operation repeatedly would not change the state of the server.
# Replace the client abc with a new resource
PUT /client/abc/ {"accountnumber":"abc" , "Name" : "Bob Jones" , "Location" : "Florida"}
The general idea behind REST is that it is used to identify a resource and then take action on that resource based on what HTTP Method is used.
If you insist on coupling your data with your view, one way accomplish this and retrieve the actual form, with the client data, could be to represent the form as a resource itself:
GET /client/abc/htmlform/
This URL would of course return your client data for client abc, but in an HTML form that would be rendered by the browser.
While my style of coding utilizes data transports such as JSON or XML to abstract and separate my data from my view, you could very well transport that data as HTML. However, the advantage of using JSON or XML is that your RESTful API becomes platform independent. If you ever expand your API to where other developers wish to consume it, they can do so, regardless of what specific platform or programming language they are using. In other words, the API could be used my PHP, Java, C#, Python, Ruby, or Perl developers.
In other words, any language or platform that can make HTTP requests and can send GET, POST, PUT, DELETE requests can be used to extend or build upon your API. This is the true advantage of REST.
For more information on setting up your controllers to use REST with Spring MVC, see this question. Additionally, check out the Spring MVC Documentation for more information.
Also, if you haven't checked out the Wikipedia article on REST, I strongly encourage you to do so. Finally, another good, classic read on REST is How I Explained REST To My Wife. Enjoy.