1559027698
In this article, you’ll learn how to create a REST API using Node.js, and secure it with OAuth 2.0 to prevent unwarranted requests. REST APIs are all over the web, but without the proper tools require a ton of boilerplate code.
JavaScript is used everywhere on the web nearly every web page will include at least some JavaScript, and even if it doesn’t, your browser probably has some sort of extension that injects bits of JavaScript code on to the page anyway. It’s hard to avoid in 2018.
JavaScript can also be used outside the context of a browser, for anything from hosting a web server to controlling an RC car or running a full-fledged operating system. Sometimes you want a couple of servers to talk to each other, whether on a local network or over the internet.
I’ll show you how to use a couple of amazing tools that make it all a breeze, including Okta to implement the Client Credentials Flow, which securely connects two machines together without the context of a user.
Setting up a web server in Node is quite simple using the Express JavaScript library. Make a new folder that will contain your server.
$ mkdir rest-api
Node uses a package.json
to manage dependencies and define your project. To create one, use npm init
, which will ask you some questions to help you initialize the project. For now, you can use standard JS to enforce a coding standard, and use that as the tests.
$ cd rest-api
$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.
See `npm help json` for definitive documentation on these fields
and exactly what they do.
Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.
Press ^C at any time to quit.
package name: (rest-api)
version: (1.0.0)
description: A parts catalog
entry point: (index.js)
test command: standard
git repository:
keywords:
author:
license: (ISC)
About to write to /Users/Braden/code/rest-api/package.json:
{
"name": "rest-api",
"version": "1.0.0",
"description": "A parts catalog",
"main": "index.js",
"scripts": {
"test": "standard"
},
"author": "",
"license": "ISC"
}
Is this OK? (yes)
The default entry point is index.js
, so you should create a new file by that name. The following code will get you a really basic server that doesn’t really do anything but listens on port 3000 by default.
index.js
const express = require('express')
const bodyParser = require('body-parser')
const { promisify } = require('util')
const app = express()
app.use(bodyParser.json())
const startServer = async () => {
const port = process.env.SERVER_PORT || 3000
await promisify(app.listen).bind(app)(port)
console.log(`Listening on port ${port}`)
}
startServer()
The promisify
function of util
lets you take a function that expects a callback and instead will return a Promise, which is the new standard as far as handling asynchronous code. This also lets us use the relatively new async
/await
syntax and make our code look much prettier.
In order for this to work, you need to install the dependencies that you require
at the top of the file. Add them using npm install
. This will automatically save some metadata to your package.json
file and install them locally in a node_modules
folder.
Note: You should never commit node_modules
to source control because it tends to become bloated quickly, and the package-lock.json
file will keep track of the exact versions you used to that if you install this on another machine they get the same code.
$ npm install express@4.16.3 util@0.11.0
For some quick linting, install standard
as a dev dependency, then run it to make sure your code is up to par.
$ npm install --save-dev standard@11.0.1
$ npm test
> rest-api@1.0.0 test /Users/bmk/code/okta/apps/rest-api
> standard
If all is well, you shouldnt see any output past the > standard
line. If there’s an error, it might look like this:
$ npm test
> rest-api@1.0.0 test /Users/bmk/code/okta/apps/rest-api
> standard
standard: Use JavaScript Standard Style (https://standardjs.com)
standard: Run `standard --fix` to automatically fix some problems.
/Users/Braden/code/rest-api/index.js:3:7: Expected consistent spacing
/Users/Braden/code/rest-api/index.js:3:18: Unexpected trailing comma.
/Users/Braden/code/rest-api/index.js:3:18: A space is required after ','.
/Users/Braden/code/rest-api/index.js:3:38: Extra semicolon.
npm ERR! Test failed. See above for more details.
Now that your code is ready and you have installed your dependencies, you can run your server with node .
(the .
says to look at the current directory, and then checks your package.json
file to see that the main file to use in this directory is index.js
):
$ node .
Listening on port 3000
To test that it’s working, you can use the curl
command. There are no endpoints yet, so express will return an error:
$ curl localhost:3000 -i
HTTP/1.1 404 Not Found
X-Powered-By: Express
Content-Security-Policy: default-src 'self'
X-Content-Type-Options: nosniff
Content-Type: text/html; charset=utf-8
Content-Length: 139
Date: Thu, 16 Aug 2018 01:34:53 GMT
Connection: keep-alive
<!DOCTYPE html>
<html lang="en">
<head>
<title>{{title}}</title>
</head>
<body>
<pre>Cannot GET /</pre>
</body>
</html>
Even though it says it’s an error, that’s good. You haven’t set up any endpoints yet, so the only thing for Express to return is a 404 error. If your server wasn’t running at all, you’d get an error like this:
$ curl localhost:3000 -i
curl: (7) Failed to connect to localhost port 3000: Connection refused
Now that you have a working Express server, you can add a REST API. This is actually much simpler than you might think. The easiest way I’ve seen is by using Sequelize to define your database schema, and Epilogue to create some REST API endpoints with near-zero boilerplate.
You’ll need to add those dependencies to your project. Sequelize also needs to know how to communicate with the database. For now, use SQLite as it will get us up and running quickly.
npm install sequelize@4.38.0 epilogue@0.7.1 sqlite3@4.0.2
Create a new file database.js
with the following code. I’ll explain each part in more detail below.
database.js
const Sequelize = require('sequelize')
const epilogue = require('epilogue')
const database = new Sequelize({
dialect: 'sqlite',
storage: './test.sqlite',
operatorsAliases: false
})
const Part = database.define('parts', {
partNumber: Sequelize.STRING,
modelNumber: Sequelize.STRING,
name: Sequelize.STRING,
description: Sequelize.TEXT
})
const initializeDatabase = async (app) => {
epilogue.initialize({ app, sequelize: database })
epilogue.resource({
model: Part,
endpoints: ['/parts', '/parts/:id']
})
await database.sync()
}
module.exports = initializeDatabase
Now you just need to import that file into your main app and run the initialization function. Make the following additions to your index.js
file.
index.js
@@ -2,10 +2,14 @@ const express = require('express')
const bodyParser = require('body-parser')
const { promisify } = require('util')
+const initializeDatabase = require('./database')
+
const app = express()
app.use(bodyParser.json())
const startServer = async () => {
+ await initializeDatabase(app)
+
const port = process.env.SERVER_PORT || 3000
await promisify(app.listen).bind(app)(port)
console.log(`Listening on port ${port}`)
You can now test for syntax errors and run the app if everything seems good:
$ npm test && node .
> rest-api@1.0.0 test /Users/bmk/code/okta/apps/rest-api
> standard
Executing (default): CREATE TABLE IF NOT EXISTS `parts` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `partNumber` VARCHAR(255), `modelNu
mber` VARCHAR(255), `name` VARCHAR(255), `description` TEXT, `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL);
Executing (default): PRAGMA INDEX_LIST(`parts`)
Listening on port 3000
In another terminal, you can test that this is actually working (to format the JSON response I use a json CLI, installed globally using npm install --global json
):
$ curl localhost:3000/parts
[]
$ curl localhost:3000/parts -X POST -d '{
"partNumber": "abc-123",
"modelNumber": "xyz-789",
"name": "Alphabet Soup",
"description": "Soup with letters and numbers in it"
}' -H 'content-type: application/json' -s0 | json
{
"id": 1,
"partNumber": "abc-123",
"modelNumber": "xyz-789",
"name": "Alphabet Soup",
"description": "Soup with letters and numbers in it",
"updatedAt": "2018-08-16T02:22:09.446Z",
"createdAt": "2018-08-16T02:22:09.446Z"
}
$ curl localhost:3000/parts -s0 | json
[
{
"id": 1,
"partNumber": "abc-123",
"modelNumber": "xyz-789",
"name": "Alphabet Soup",
"description": "Soup with letters and numbers in it",
"createdAt": "2018-08-16T02:22:09.446Z",
"updatedAt": "2018-08-16T02:22:09.446Z"
}
]
Feel free to skip this section if you followed along with all that, but I did promise an explanation.
The Sequelize
function creates a database. This is where you configure details, such as what dialect of SQL to use. For now, use SQLite to get up and running quickly.
const database = new Sequelize({
dialect: 'sqlite',
storage: './test.sqlite',
operatorsAliases: false
})
Once you’ve created the database, you can define the schema for it using database.define
for each table. Create a table called parts
with a few useful fields to keep track of parts. By default, Sequelize also automatically creates and updates id
, createdAt
, and updatedAt
fields when you create or update a row.
const Part = database.define('parts', {
partNumber: Sequelize.STRING,
modelNumber: Sequelize.STRING,
name: Sequelize.STRING,
description: Sequelize.TEXT
})
Epilogue requires access to your Express app
in order to add endpoints. However, app
is defined in another file. One way to deal with this is to export a function that takes the app and does something with it. In the other file when we import this script, you would run it like initializeDatabase(app)
.
Epilogue needs to initialize with both the app
and the database
. You then define which REST endpoints you would like to use. The resource
function will include endpoints for the GET
, POST
, PUT
, and DELETE
verbs, mostly automagically.
To actually create the database, you need to run database.sync()
, which returns a Promise. You’ll want to wait until it’s finished before starting your server.
The module.exports
command says that the initializeDatabase
function can be imported from another file.
const initializeDatabase = async (app) => {
epilogue.initialize({ app, sequelize: database })
epilogue.resource({
model: Part,
endpoints: ['/parts', '/parts/:id']
})
await database.sync()
}
module.exports = initializeDatabase
Now that you have a REST API up and running, imagine you’d like a specific application to use this from a remote location. If you host this on the internet as is, then anybody can add, modify, or remove parts at their will.
To avoid this, you can use the OAuth 2.0 Client Credentials Flow. This is a way of letting two servers communicate with each other, without the context of a user. The two servers must agree ahead of time to use a third-party authorization server. Assume there are two servers, A and B, and an authorization server. Server A is hosting the REST API, and Server B would like to access the API.
This is where Okta comes into play. Okta can act as an authorization server to allow you to secure your data.
You’re probably asking yourself “Why Okta? Well, it’s pretty cool to build a REST app, but it’s even cooler to build a secure one. To achieve that, you’ll want to add authentication so users have to log in before viewing/modifying groups. At Okta, our goal is to make identity management a lot easier, more secure, and more scalable than what you’re used to. Okta is a cloud service that allows developers to create, edit, and securely store user accounts and user account data, and connect them with one or multiple applications.
After creating your account, log in to your developer console, navigate to API, then to the Authorization Servers tab. Click on the link to your default
server.
From this Settings tab, copy the Issuer
field. You’ll need to save this somewhere that your Node app can read. In your project, create a file named .env
that looks like this:
.env
ISSUER=https://{yourOktaDomain}/oauth2/default
The value for ISSUER
should be the value from the Settings page’s Issuer URI
field.
Note: As a general rule, you should not store this .env
file in source control. This allows multiple projects to use the same source code without needing a separate fork. It also makes sure that your secure information is not public (especially if you’re publishing your code as open source).
Next, navigate to the Scopes tab. Click the Add Scope button and create a scope for your REST API. You’ll need to give it a name (e.g. parts_manager
) and you can give it a description if you like.
You should add the scope name to your .env
file as well so your code can access it.
.env
ISSUER=https://{yourOktaDomain}/oauth2/default
SCOPE=parts_manager
Now you need to create a client. Navigate to Applications, then click Add Application. Select Service, then click Next. Enter a name for your service, (e.g. Parts Manager
), then click Done.
This will take you to a page that has your client credentials. These are the credentials that Server B (the one that will consume the REST API) will need in order to authenticate. For this example, the client and server code will be in the same repository, so go ahead and add this data to your .env
file. Make sure to replace {yourClientId}
and {yourClientSecret}
with the values from this page.
CLIENT_ID={yourClientId}
CLIENT_SECRET={yourClientSecret}
In Express, you can add middleware that will run before each endpoint. You can then add metadata, set headers, log some information, or even cancel the request early and send an error message. In this case, you’ll want to create some middleware that verifies the token sent by the client. If the token is valid, it will continue to the REST API and return the appropriate response. If the token is invalid, it will instead respond with an error message so that only authorized machines have access.
To validate tokens, you can use Okta’s middleware. You’ll also need a tool called dotenv to load the environment variables:
npm install dotenv@6.0.0 @okta/jwt-verifier@0.0.12
Now create a file named auth.js
that will export the middleware:
auth.js
const OktaJwtVerifier = require('@okta/jwt-verifier')
const oktaJwtVerifier = new OktaJwtVerifier({ issuer: process.env.ISSUER })
module.exports = async (req, res, next) => {
try {
const { authorization } = req.headers
if (!authorization) throw new Error('You must send an Authorization header')
const [authType, token] = authorization.trim().split(' ')
if (authType !== 'Bearer') throw new Error('Expected a Bearer token')
const { claims } = await oktaJwtVerifier.verifyAccessToken(token)
if (!claims.scp.includes(process.env.SCOPE)) {
throw new Error('Could not verify the proper scope')
}
next()
} catch (error) {
next(error.message)
}
}
This function first checks that the authorization
header is on the request and throws an error otherwise. If it exists, it should look like Bearer {token}
where {token}
is a JWT string. This will throw another error if the header doesn’t start with Bearer
. Then we send the token to Okta’s JWT Verifier to validate the token. If the token is invalid, the JWT verifier will throw an error. Otherwise, it will return an object with some information. You can then verify that the claims include the scope that you’re expecting.
If everything is successful, it calls the next()
function without any parameters, which tells Express that it’s OK to move on to the next function in the chain (either another middleware or the final endpoint). If you pass a string into the next
function, Express treats it as an error that will be passed back to the client, and will not proceed in the chain.
You still need to import this function and add it as middleware to your app. You also need to load dotenv
at the top of your index file to make sure that the environment variables from .env
are loaded in your app. Make the following changes to index.js
:
index.js
@@ -1,11 +1,14 @@
+require('dotenv').config()
const express = require('express')
const bodyParser = require('body-parser')
const { promisify } = require('util')
+const authMiddleware = require('./auth')
const initializeDatabase = require('./database')
const app = express()
app.use(bodyParser.json())
+app.use(authMiddleware)
const startServer = async () => {
await initializeDatabase(app)
To test that requests are properly blocked, try running it again…
$ npm test && node .
…then in another terminal run a few curl
commands to test for:
$ curl localhost:3000/parts
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<pre>You must send an Authorization header</pre>
</body>
</html>
$ curl localhost:3000/parts -H 'Authorization: Basic asdf:1234'
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<pre>Expected a Bearer token</pre>
</body>
</html>
$ curl localhost:3000/parts -H 'Authorization: Bearer asdf'
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<pre>Jwt cannot be parsed</pre>
</body>
</html>
You have now disabled access to the app for someone without a valid token, but how do you get a token and use it? I’ll show you how to write a simple client in Node, which will also help you test that a valid token works.
npm install btoa@1.2.1 request-promise@4.2.2
client.js
require('dotenv').config()
const request = require('request-promise')
const btoa = require('btoa')
const { ISSUER, CLIENT_ID, CLIENT_SECRET, SCOPE } = process.env
const [,, uri, method, body] = process.argv
if (!uri) {
console.log('Usage: node client {url} [{method}] [{jsonData}]')
process.exit(1)
}
const sendAPIRequest = async () => {
const token = btoa(`${CLIENT_ID}:${CLIENT_SECRET}`)
try {
const auth = await request({
uri: `${ISSUER}/v1/token`,
json: true,
method: 'POST',
headers: {
authorization: `Basic ${token}`
},
form: {
grant_type: 'client_credentials',
scope: SCOPE
}
})
const response = await request({
uri,
method,
body,
headers: {
authorization: `${auth.token_type} ${auth.access_token}`
}
})
console.log(response)
} catch (error) {
console.log(`Error: ${error.message}`)
}
}
sendAPIRequest()
Here the code is loading the variables from .env
into the environment, then grabbing them from Node. Node stores environment variables in process.env
(process
is a global variable with a bunch of useful variables and functions).
require('dotenv').config()
// ...
const { ISSUER, CLIENT_ID, CLIENT_SECRET, SCOPE } = process.env
// ...
Next, since this will be run from the command line, you can use process
again to grab the arguments passed in with process.argv
. This gives you an array with all the arguments passed in. The first two commas are there without variable names in front of them because the first two are unimportant in this case; those will just be the path to node
, and the name of the script (client
or client.js
).
The URL is required, which would include the endpoint, but the method and JSON data are optional. The default method is GET
, so if you’re just fetching data you can leave that out. You also wouldn’t need any payload in that case. If the arguments don’t seem right, then this will exit the program with an error message and an exit code of 1
, signifying an error.
const [,, uri, method, body] = process.argv
if (!uri) {
console.log('Usage: node client {url} [{method}] [{jsonData}]')
process.exit(1)
}
Node currently doesn’t allow for await
in the main thread, so to make use of the cleaner async
/await
syntax, you have to create a function and then call it afterward.
If an error occurs in any of the await
ed functions, the try
/catch
they’ll be printed out to the screen.
const sendAPIRequest = async () => {
try {
// ...
} catch (error) {
console.error(`Error: ${error.message}`)
}
}
sendAPIRequest()
This is where the client sends a request to the authorization server for a token. For authorizing with the authorization server itself, you need to use Basic Auth. Basic Auth is the same thing a browser uses when you get one of those built-in pop-ups asking for a username and password. Say your username is AzureDiamond
and your password is hunter2
. Your browser would then concatenate them together with a colon (:
) and then encode them with base64 (this is what the btoa
function does) to get QXp1cmVEaWFtb25kOmh1bnRlcjI=
. It then sends an authorization header of Basic QXp1cmVEaWFtb25kOmh1bnRlcjI=
. The server can then decode the token with base64 to get the username and password.
Basic authorization isn’t inherently secure because it’s so easy to decode, which is why https
is important, to prevent a man-in-the-middle attack. Here, the client ID and client secret are the username and password, respectively. That’s also why it’s important to keep your CLIENT_ID
and CLIENT_SECRET
private.
For OAuth 2.0, you also need to specify the grant type, which in this case is client_credentials
since you’re planning to talk between two machines. You also need to specify the scope. There are a lot of other options that could be added here, but this is all we need for this demo.
const token = btoa(`${CLIENT_ID}:${CLIENT_SECRET}`)
const auth = await request({
uri: `${ISSUER}/v1/token`,
json: true,
method: 'POST',
headers: {
authorization: `Basic ${token}`
},
form: {
grant_type: 'client_credentials',
scope: SCOPE
}
})
Once you’re authenticated, you’ll get an access token that you can send along to your REST API that should look something like Bearer eyJra...HboUg
(the actual token is much longer than that – likely somewhere around 800 characters). The token contains all the information needed for the REST API to verify who you are, when the token will expire, and all kinds of other information, like the scopes requested, the issuer, and the client ID used to request the token.
The response from the REST API is then printed to the screen.
const response = await request({
uri,
method,
body,
headers: {
authorization: `${auth.token_type} ${auth.access_token}`
}
})
console.log(response)
Go ahead and test it out now. Again, start the app with npm test && node .
, then try out some commands like the following:
$ node client http://localhost:3000/parts | json
[
{
"id": 1,
"partNumber": "abc-123",
"modelNumber": "xyz-789",
"name": "Alphabet Soup",
"description": "Soup with letters and numbers in it",
"createdAt": "2018-08-16T02:22:09.446Z",
"updatedAt": "2018-08-16T02:22:09.446Z"
}
]
$ node client http://localhost:3000/parts post '{
"partNumber": "ban-bd",
"modelNumber": 1,
"name": "Banana Bread",
"description": "Bread made from bananas"
}' | json
{
"id": 2,
"partNumber": "ban-bd",
"modelNumber": "1",
"name": "Banana Bread",
"description": "Bread made from bananas",
"updatedAt": "2018-08-17T00:23:23.341Z",
"createdAt": "2018-08-17T00:23:23.341Z"
}
$ node client http://localhost:3000/parts | json
[
{
"id": 1,
"partNumber": "abc-123",
"modelNumber": "xyz-789",
"name": "Alphabet Soup",
"description": "Soup with letters and numbers in it",
"createdAt": "2018-08-16T02:22:09.446Z",
"updatedAt": "2018-08-16T02:22:09.446Z"
},
{
"id": 2,
"partNumber": "ban-bd",
"modelNumber": "1",
"name": "Banana Bread",
"description": "Bread made from bananas",
"createdAt": "2018-08-17T00:23:23.341Z",
"updatedAt": "2018-08-17T00:23:23.341Z"
}
]
$ node client http://localhost:3000/parts/1 delete | json
{}
$ node client http://localhost:3000/parts | json
[
{
"id": 2,
"partNumber": "ban-bd",
"modelNumber": "1",
"name": "Banana Bread",
"description": "Bread made from bananas",
"createdAt": "2018-08-17T00:23:23.341Z",
"updatedAt": "2018-08-17T00:23:23.341Z"
}
]
☞ Building A REST API With MongoDB, Mongoose, And Node.js
☞ Creating RESTful APIs with NodeJS and MongoDB Tutorial
☞ How to build RESTful APIs with ASP.NET Core
☞ Understanding the basics of RESTful APIs
☞ Build a CRUD App with Angular and Firebase
☞ The Complete Node.js Developer Course (2nd Edition)
☞ Angular (Angular 2+) & NodeJS - The MEAN Stack Guide
☞ Beginner Full Stack Web Development: HTML, CSS, React & Node
#node-js #rest #api #web-development
1594289280
The REST acronym is defined as a “REpresentational State Transfer” and is designed to take advantage of existing HTTP protocols when used for Web APIs. It is very flexible in that it is not tied to resources or methods and has the ability to handle different calls and data formats. Because REST API is not constrained to an XML format like SOAP, it can return multiple other formats depending on what is needed. If a service adheres to this style, it is considered a “RESTful” application. REST allows components to access and manage functions within another application.
REST was initially defined in a dissertation by Roy Fielding’s twenty years ago. He proposed these standards as an alternative to SOAP (The Simple Object Access Protocol is a simple standard for accessing objects and exchanging structured messages within a distributed computing environment). REST (or RESTful) defines the general rules used to regulate the interactions between web apps utilizing the HTTP protocol for CRUD (create, retrieve, update, delete) operations.
An API (or Application Programming Interface) provides a method of interaction between two systems.
A RESTful API (or application program interface) uses HTTP requests to GET, PUT, POST, and DELETE data following the REST standards. This allows two pieces of software to communicate with each other. In essence, REST API is a set of remote calls using standard methods to return data in a specific format.
The systems that interact in this manner can be very different. Each app may use a unique programming language, operating system, database, etc. So, how do we create a system that can easily communicate and understand other apps?? This is where the Rest API is used as an interaction system.
When using a RESTful API, we should determine in advance what resources we want to expose to the outside world. Typically, the RESTful API service is implemented, keeping the following ideas in mind:
The features of the REST API design style state:
For REST to fit this model, we must adhere to the following rules:
#tutorials #api #application #application programming interface #crud #http #json #programming #protocols #representational state transfer #rest #rest api #rest api graphql #rest api json #rest api xml #restful #soap #xml #yaml
1604399880
I’ve been working with Restful APIs for some time now and one thing that I love to do is to talk about APIs.
So, today I will show you how to build an API using the API-First approach and Design First with OpenAPI Specification.
First thing first, if you don’t know what’s an API-First approach means, it would be nice you stop reading this and check the blog post that I wrote to the Farfetchs blog where I explain everything that you need to know to start an API using API-First.
Before you get your hands dirty, let’s prepare the ground and understand the use case that will be developed.
If you desire to reproduce the examples that will be shown here, you will need some of those items below.
To keep easy to understand, let’s use the Todo List App, it is a very common concept beyond the software development community.
#api #rest-api #openai #api-first-development #api-design #apis #restful-apis #restful-api
1602725748
APIs have been around for decades – they allow different systems to talk to each other in a seamless, fast fashion – yet it’s been during the past decade that this technology has become a significant force.
So then why all the interest in APIs? We all know the usual stories – Uber, Airbnb, Apple Pay… the list goes on, and the reasons are plentiful. Today the question is, how? Perhaps you are looking to differentiate your business or want a first-mover advantage. How can you execute quickly and at low cost/risk to try new market offerings?
An API provides several benefits to an organisation, but without a dedicated team of trained developers, it might seem like an implausible option. Developers are expensive, and it can take months to develop an API from the ground up. If you don’t fancy outsourcing or have the capability in house to build internal APIs, a low-code platform might just be the answer.
For a small one-page application, this might only be a day or two of talking with stakeholders and designing business logic. The purpose of this first step is to ensure that the API will cover all use cases and provides stakeholders with what they need. Refactoring an entire coding design due to missing business logic is not only frustrating for the development team but adds high cost and time to the API project.
During the planning and design stage, remember that running an API requires more infrastructure than just resources to execute endpoint logic. You need a database to store the data, an email system to send messages, storage for files, and security to handle authorisation and authentication. These services can be farmed out to cloud providers to expedite the API build process (e.g. AWS provides all these infrastructure components, but Microsoft Azure is an optional cloud provider with SendGrid as the email application.)
**Planning considerations: **An API “speaks” in JSON or XML, so the output provided to client applications should be decided. Should you choose to later create endpoints for public developer consumption, you could offer both for ease-of-use and fostering more adoption. Ensuring the API follows OpenAPI standards will encourage more adoption and attract more developers.
#api #rest-api #api-development #restful-api #low-code-platform #low-code #build-a-rest-api #low-code-approach
1602682740
In the API economy, a successful service can gain popularity and be utilized in ways unpredicted and often inconceivable by its original owners. The very flexible nature of the technology opens many doors, including business collaborations, reuse in third-party products or even conquering hardware barriers by reaching a spectrum of devices.
Taking the builder’s perspective
Important note: Most of the time API consumers are not the end-users but rather the app developers. Any new venture ought to be supported with excellent learning resources and descriptive documentation. These things combined will ensure a top-notch developer experience and encourage adoption of your product, increasing its visibility in the market.
More than the revenue
While in the simplest scenario, the most popular API business model is revenue via service charges, there are several other goals:
#api #api-development #api-integration #restful-api #api-based-business-model #api-first-development #automation #rest-api
1596509565
In this tutorial I will show you the fundamentals of designing a RESTful API specification by applying REST principles and best practices, then you’ll be ready to try my online tutorial: How to design a REST API with API Designer?
If you already know what is meant by API in the context of RESTful web services, you can skip to the next section. If not, read on.
The abbreviation API stands for Application Programming Interface this in itself, does not help us understand what it is, however in the context of web services, it can refer to one of two things:
In this post, I will use the first understanding of this term. Even though both are correct, the most technically relevant for this post is the first: an API is a contract for how software applications talk to each other.
The acronym REST stands for REpresentational State Transfer. It is an architectural style used to represent the transmission of data from one application component to another. In the context of web services, we are talking about the representation of resources (i.e. data) transferred over HTTP by calling a URI that represents the data and via an HTTP method that represents the action to perform against the given data.
RESTful API design is the activity of describing the behavior of a web service in terms of its data structures and the actions you allow other application components to perform on its data by the principles of REST. Those principles are covered later in this blog.
Imagine that you are an Architect (the kind the design building) and you set out to build an office block without a blueprint. You turn up on the first day with a truck full of bricks and some cement. What are the chances that you’ll be successful and build a structure that conforms to code and more importantly, doesn’t fall? It’s about zero. Without a blueprint the chance of failure is high.
The same approach applies to web service development. You need a blueprint, or more appropriately, an API specification. This is necessary to evaluate the API design and solicit feedback before even starting to build the implementation.
In addition to providing a specification for the web service’s development, an API contract serves to document its expected behavior, data types, and security requirements.
You should now be satisfied that API design is necessary for a RESTful web service, and should start to wonder how is the best approach to actually designing an API specification.
The tooling chosen by an API designer has substantial influence over the designer’s productivity. Highly productive tools such as the Anypoint API Designer from MuleSoft is perfect for designing APIs with OAS (swagger) or RAML.
#integration #api #rest #rest api #restful #api design #raml #rest api design