Is RESTful API over-used/mis-used? - web-services

I just spent a whole day reading the Fielding's famous dissertation on REST. It says at the Conclusion part that :
REST, a novel architectural style for distributed hypermedia systems.
...
Although Web-based applications can include access to other styles of
interaction, the central focus of its protocol and performance
concerns is distributed hypermedia. REST elaborates only those
portions of the architecture that are considered essential for
Internet-scale distributed hypermedia interaction.
And according to Wikipedia:
Hypermedia, an extension of the term hypertext, is a nonlinear medium
of information which includes graphics, audio, video, plain text and
hyperlinks.
So it appears to me REST is kind of meant for web-based content-intensive system. But obviously RESTful API has been a buzzword used in almost everywhere regarding web service.
So is this kind of over-use? Or mis-use?
Refs:
RESTful APIs, the big lie.
What exactly is RESTful programming?
What does "hypermedia data formats" mean in Fielding's famous dissertation when talking about Cookies

I think JSON is not more or less media than text or video are. So in essence, a serialized object represented in JSON is a medium.
Now "hypermedia" is media that is linked together semantically. You can make JSON hypermedia by including links: HAL, or HATEAOS.
Herein you add links to related resources to a JSON document. Example:
{
"content": [ {
"price": 499.00,
"description": "Apple tablet device",
"name": "iPad",
"links": [ {
"rel": "self",
"href": "http://localhost:8080/product/1"
} ],
"attributes": {
"connector": "socket"
}
}, {
"price": 49.00,
"description": "Dock for iPhone/iPad",
"name": "Dock",
"links": [ {
"rel": "self",
"href": "http://localhost:8080/product/3"
} ],
"attributes": {
"connector": "plug"
}
} ],
"links": [ {
"rel": "product.search",
"href": "http://localhost:8080/product/search"
} ]
}
People argue that without links, JSON is not hypermedia.
I'm also a big fan of not trying to cram every API into REST. Not every API is about resources, so if your API represents RPC instead, call it what it is: an RPC API.

Related

Reusable State Definition in Step Functions

We are creating a workflow composed of multiple SQL Operations(Aggregations, Transposes etc.) via AWS Step functions. Every operation is modelled as a separate Lambda which houses the SQL query.
Now, every query accepts its input parameters from the state machine, so every lambda task is as below:
"SQLQueryTask": {
"Type": "Task",
"Parameters": {
"param1.$": "$$.Execution.Input.param1",
"param2.$": "$$.Execution.Input.param2"
},
"Resource": "LambdaArn",
"End": true
}
The Parameters block thus repeats for every SQLQuery node.
Added to this since Lambdas can fail intermittently and we would like to retry for them ; we also need to have below retry block in every State:
"Retry": [ {
"ErrorEquals": [ "Lambda.ServiceException", "Lambda.AWSLambdaException", "Lambda.SdkClientException"],
"IntervalSeconds": 2,
"MaxAttempts": 6,
"BackoffRate": 2
} ]
This is making the state definition very complex. Is there No way to extract out the common part of state definition to a reusable piece?
One solution could be using AWS CDK (https://aws.amazon.com/cdk/)
This allows developers to define higher-level abstractions of resources, which can easily be reused.
There are some example here that could be helpful: https://docs.aws.amazon.com/cdk/api/latest/docs/aws-stepfunctions-readme.html

How to lock files with TFVC REST API?

I'm trying to create a C++ library that uses the TFVC REST API so that I can support TFS from within a program.
I've been successful using rapidjson and chilkat to build and send requests for a lot of the functionality so far-- add, delete, rename, etc.
My issue is that I cannot seem to apply any locks. I want users to be able to 'checkout' a file and to do so a lock must be applied.
This is for a TFS 2017 Server. Here's a link to the TFVC REST API docs
https://learn.microsoft.com/en-us/rest/api/azure/devops/tfvc/changesets/create?view=azure-devops-rest-5.0#versioncontrolchangetype
Here's my test:
{
"changes":[
{
"changeType":"lock",
"item":{
"contentMetadata":{
"contentType":"rawText",
"encoding":1200
},
"path":"$/TFStestAT/TextFile1.txt",
"version":"131"
}
}
],
"comment":"(sample) Locking a file via Advanced REST Client"
}
Here's the response:
{
"$id": "1",
"innerException": null,
"message": "The specified change type Lock is not supported.",
"typeName": "System.ArgumentException, mscorlib",
"typeKey": "ArgumentException",
"errorCode": 0,
"eventId": 0
}
With no "checkout" changeType and Lock not being supported, how should I go about locking?
Any tips would be greatly appreciated!

Is there anyway to determine what IAM permissions I actually need for a CloudFormation template?

Just wondering whats the best practice for determining what permissions I should give for my CloudFormation template?
After some time of trying to give the minimal permissions it require, I find that thats really time consuming and error prone. I note that depending on the state of my stack, really new vs some updates vs delete, I will need different permissions.
I guess, it should be possible for there to be some parser that given a CloudFormation template can determine the minimum set of permissions it require?
Maybe I can give ec2:* access to resources tagged Cost Center: My Project Name? Is this ok? But I wonder what happens when I change my project name for example?
Alternatively, isit ok to assume its ok to give say ec2:* access based on the assumption the CloudFormation parts is usually only executed off CodeCommit/Github/CodePipeline and its not something that is likely to be public/easy to hack? --- Tho this sounds like a flawed statement to me ...
In the short term, you can use aws-leastprivilege. But it doesn't support every resource type.
For the long term: as mentioned in this 2019 re:invent talk, CloudFormation is working towards open sourcing and migrating most of its resource types to a new public resource schema. One of the benefits of this is that you'll be able to see the permissions required to perform each operation.
E.g. for AWS::ImageBuilder::Image, the schema says
"handlers": {
"create": {
"permissions": [
"iam:GetRole",
"imagebuilder:GetImageRecipe",
"imagebuilder:GetInfrastructureConfiguration",
"imagebuilder:GetDistributionConfiguration",
"imagebuilder:GetImage",
"imagebuilder:CreateImage",
"imagebuilder:TagResource"
]
},
"read": {
"permissions": [
"imagebuilder:GetImage"
]
},
"delete": {
"permissions": [
"imagebuilder:GetImage",
"imagebuilder:DeleteImage",
"imagebuilder:UnTagResource"
]
},
"list": {
"permissions": [
"imagebuilder:ListImages"
]
}
}

How can I install the sample AdventureWorksDW database on SQL DW using an ARM script

I can create a SQL DW using ARM no problem. However, the portal supports an option of also installing a sample database - e.g. AdventureWorksDW. How can I do the equivalent using an ARM script?
BTW, I clicked on "automation options" on the portal add it shows an ARM script with an extension that probably is the piece that installs the sample database, but it asks for some parameters (e.g. storageKey, storageUri) that I don't know.
Here's what I think is the relevant portion of the ARM JSON:
"name": "PolybaseImport",
"type": "extensions",
"apiVersion": "2014-04-01-preview",
"dependsOn": [
"[concat('Microsoft.Sql/servers/', parameters('serverName'), '/databases/', parameters('databaseName'))]"
],
"properties": {
"storageKeyType": "[parameters('storageKeyType')]",
"storageKey": "[parameters('storageKey')]",
"storageUri": "[parameters('storageUri')]",
"administratorLogin": "[parameters('administratorLogin')]",
"administratorLoginPassword": "[parameters('administratorLoginPassword')]",
"operationMode": "PolybaseImport"
}
More specifically, looking at the ARM deploy script generated from the portal, here are the key elements that I need to know in order to auto deploy using my own ARM script:
…
"storageKey": {
"value": null  <- without knowing this, I can’t deploy.
},
"storageKeyType": {
"value": "SharedAccessKey"
},
"storageUri": {
"value": https://sqldwsamplesdefault.blob.core.windows.net/adventureworksdw/AdventureWorksDWPolybaseImport/Manifest.xml  <- this is not a public blob, so can’t look at it
},
…
AFAIK that's currently not possible. The portal kicks off a workflow that provisions the new DW resources, generates the sample DW schema then loads data. The sample is stored in a non-public blob so you won't be able to access it.
I don't think it's hard to make it available publicly but it does take some work so perhaps you should add a suggestion here: https://feedback.azure.com/forums/307516-sql-data-warehouse

View attachments in threads

I'm currently working on an alternative way to view the threads and messages. But I have problems figuring out how to display the images attached to a message.
I have a GET request to this url: https://graph.facebook.com/t_id.T_ID/messages?access_token=ACCESS_TOKEN. And the response includes
"attachments": {
"data": [
{
"id": "df732cf372bf07f29030b5d44313038c",
"mime_type": "image/jpeg",
"name": "image.jpg",
"size": 76321
}
]
}
but I can't find any way to access the image.
Thanks
Support for this hasn't yet been added to the Graph API and as with many of the other messaging APIs, it's currently only avaialable for testing (i.e you must be a developer of the app to use it presently)
There's an undocumented REST API endpoint for this, which should work for any app (that you're the developer of, as above).
To use the REST method to get the attachment data, it's
https://api.facebook.com/method/messaging.getattachment
With parameters:
access_token=YOUR_ACCESS_TOKEN
mid=MESSAGE_ID
aid=ATTACHMENT_ID
format=json //(it defaults to XML otherwise)
The response is like this:
{"content_type":"image\/png","filename":"Screen Shot 2012-02-08 at 11.35.35.png","file_size":42257,"data":<FILE CONTENTS>}
I've just tested this and it worked OK for me, taking the <FILE CONTENTS> and base64 decoding them gave me back the original image correctly