Professional Documents
Culture Documents
mulesoft_nodejs
mulesoft_nodejs
mulesoft_nodejs
This repository has been archived by the owner on May 10, 2024. It is now read-only.
View license
Star Notifications
jstoiko Merge pull request #205 from mulesoft/rework_webapi_parser b7481e9 · 4 years ago
README License
Osprey
npm v1.0.0 downloads 1.9k/month Build status coverage 97% Greenkeeper Move to Snyk
Generate API middleware from a RAML definition, which can be used locally or globally for validating API requests and responses.
Features
Automatic Request Validations
Bodies
Form data
Url Encoded bodies
JSON schemas
XML schemas
https://github.com/mulesoft/osprey 1/10
7/8/24, 11:46 AM GitHub - mulesoft/osprey: Generate Node.JS API middleware from a RAML definition
Headers
Query parameters
RAML 1.0 types
Automatic Request Parameters
Default Headers
Default Parameters
RAML Router
Uses osprey-router for RAML paths
Integrates with Express-format middleware servers
Simple req / res / next middleware format that works with Connect, Express and even http
API documentation Currently disabled
Optionally mount API documentation generated from your RAML definition
Built-in Error Handling Middleware
I18n support
Map validation paths to readable strings (with i18n support)
Built-in Response Handling Coming soon
Validate response bodies against status code definition
Automatically fill default response headers
Authentication
OAuth 1.0 Coming Soon
OAuth 2.0
Basic Authentication
Digest Authentication
Custom Security Schemes
RAML Mock Service
Server
Security
Installation
Global
Osprey can be used as a validation proxy with any other API server. Just install the module globally and use the CLI to set up the
application endpoint(s) to proxy, as well as the RAML definition to use. Invalid API requests will be blocked before they reach your
application server.
https://github.com/mulesoft/osprey 2/10
7/8/24, 11:46 AM GitHub - mulesoft/osprey: Generate Node.JS API middleware from a RAML definition
osprey -f api.raml -p 3000 -a localhost:8080
Options
-a Application endpoint address (can be fully qualified URLs) and specify multiple, comma-separated addresses
Locally
Usage
Osprey is normally used as a local node module and is compatible with any library supporting HTTP middleware, including Express and
Connect. Just require the module locally and generate the middleware from a RAML definition file.
// Be careful, this uses all middleware functions by default. You might just
// want to use each one separately instead - `osprey.server`, etc.
osprey.loadFile(path)
.then(function (middleware) {
app.use(middleware)
app.listen(3000)
})
.catch(function(e) { console.error("Error: %s", e.message); });
Please note: The middleware function does not use the RAML baseUri . Make sure you mount the application under the correct path.
E.g. app.use('/v1', middleware) .
// webapi-parser.WebApiDocument
const model = wap.raml10.parse('/some/api.raml')
const handler = osprey.server(model, options)
Options
cors Enable CORS by setting to true or an object from cors (default: false )
compression Enable response compression using compression (default: false )
https://github.com/mulesoft/osprey 3/10
7/8/24, 11:46 AM GitHub - mulesoft/osprey: Generate Node.JS API middleware from a RAML definition
notFoundHandler Use a 404 error in middleware to skip over invalid/undefined routes from RAML (default: true )
If you disable the default "not found" handler, it should be mounted later using osprey.server.notFoundHandler . For example,
app.use(osprey.server.notFoundHandler) .
Invalid headers and query parameters are removed from the request. To read them they need to be documented in the RAML definition.
Request Bodies
Request bodies are parsed and validated for you, when you define the schema.
For application/json and application/x-www-form-urlencoded , the data will be an object under req.body . For text/xml , the body is
stored as a string under req.body while the parsed XML document is under req.xml (uses LibXMLJS, not included). For
multipart/form-data , you will need to attach field and file listeners to the request form (uses Busboy):
req.form.on('error', next)
req.pipe(req.form)
})
All parameters are automatically validated and parsed to the correct types according to the RAML document using webapi-parser and
raml-sanitize. URL parameter validation comes with Osprey Router, available using osprey.Router .
// Array<webapi-parser.Parameter>
const parameters = utils.getUriParameters()
app.use(...)
https://github.com/mulesoft/osprey 4/10
7/8/24, 11:46 AM GitHub - mulesoft/osprey: Generate Node.JS API middleware from a RAML definition
module.exports = app
You can initialize a Router with ramlUriParameters . This is helpful, since every router collects an object with merged URI parameters.
For example, you can combine it with the server middleware to generate a router with your RAML URI parameters:
Handling Errors
Osprey returns a middleware router instance, so you can mount this within any compatible application and handle errors with the
framework. For example, using HTTP with finalhandler (the same module Express uses):
osprey.loadFile(join(__dirname, 'api.raml'))
.then(function (middleware) {
http.createServer(function (req, res) {
middleware(req, res, finalhandler(req, res))
}).listen(process.env.PORT || 3000)
})
.catch(function(e) { console.error("Error: %s", e.message); });
Error Types
error.ramlAuthorization = true An unauthorized error containing an array of errors that occured is set on
error.authorizationErrors
error.ramlValidation = true A request failed validation and an array of validation data is set on error.requestErrors (beware,
different types contain different information)
error.ramlNotFound = true A request 404'd because it was not specified in the RAML definition for the API
JSON schemas can be added to the application for when external JSON references are needed. From osprey-method-handler.
osprey.addJsonSchema(schema, key)
Error Handler
Osprey comes with support for a built-in error handler middleware that formats request errors for APIs. It comes with built-in i18n with
some languages already included for certain formats (help us add more!). The default fallback language is en and the default responder
renders JSON, XML, HTML and plain text - all options are overridable.
// It's best to use the default responder, but it's overridable if you need it.
app.use(osprey.errorHandler(function (req, res, errors, stack) { /* Override */ }, 'en'))
You can override the i18n messages or provide your own by passing a nested object that conforms to the following interface:
https://github.com/mulesoft/osprey 5/10
7/8/24, 11:46 AM GitHub - mulesoft/osprey: Generate Node.JS API middleware from a RAML definition
interface CustomMessages {
[type: string]: {
[keyword: string]: {
[language: string]: (error: RequestError) => string
}
}
}
interface RequestError {
type: 'json' | 'form' | 'headers' | 'query' | 'xml' | string
message: string /* Merged with i18n when available */
keyword: string /* Keyword that failed validation */
id?: string /* A unique identifier for the instance of this error */
dataPath?: string /* Natural path to the error message (E.g. JSON Pointers when using JSON) */
data?: any /* The data that failed validation */
schema?: any /* The schema value that failed validation */
detail?: string /* Additional details about this specific error instance */
meta?: { [name: string]: string } /* Meta data from the error (XML validation provides a code, column, etc.) */
}
Want to format your own request errors? If you emit an error with a .status property of "client error" ( 400 - 499 ) and an array of
requestErrors , it will automatically be rendered as the API response (using status as the response status code).
Security
Osprey accepts an options object that maps object keys to the security scheme name in the RAML definition.
OAuth 2.0
securitySchemes:
- oauth_2_0:
type: OAuth 2.0
settings:
authorizationUri: https://example.com/oauth/authorize
accessTokenUri: https://example.com/oauth/token
authorizationGrants: [ code, token, owner, credentials ]
scopes:
- profile
- history
- history_lite
- request
- request_receipt
OAuth 2.0 can be fairly tricky to enforce on your own. With Osprey, any endpoint with securedBy will automatically be enforced.
All
authenticateClient
serializeClient
https://github.com/mulesoft/osprey 6/10
7/8/24, 11:46 AM GitHub - mulesoft/osprey: Generate Node.JS API middleware from a RAML definition
deserializeClient
authorizeClient
sessionKeys
Code
grant.code
exchange.code
Token
grant.token
Credentials
exchange.credentials
Owner
exchange.owner
The authorization page must submit a POST request to the same URL with the transaction_id and scope properties set (from
req.oauth2 ). If the dialog was denied, submit cancel=true with the POST body. If you wish to enable the ability to skip the
authorization page (E.g. user already authorized or first-class client), use the immediateAuthorization option.
https://github.com/mulesoft/osprey 7/10
7/8/24, 11:46 AM GitHub - mulesoft/osprey: Generate Node.JS API middleware from a RAML definition
},
// An array of unique session keys to sign and verify cookies.
sessionKeys: ['a', 'b', 'c', ...],
ensureLoggedIn: function (req, res, next) {
// For example: https://github.com/jaredhanson/connect-ensure-login
},
immediateAuthorization: function (client, user, scope, done) {
return done(null, false)
},
serveAuthorizationPage: function (req, res) {
res.render('dialog', {
transactionId: req.oauth2.transactionID,
user: req.user,
client: req.oauth2.client
})
},
grant: {
code: function (client, redirectUri, user, ares, done) {
AuthorizationCode.create(client.id, redirectUri, user.id, ares.scope, function (err, code) {
if (err) { return done(err) }
done(null, code)
})
},
token: function (client, user, ares, done) {
AccessToken.create(client, user, ares.scope, function (err, accessToken) {
if (err) { return done(err) }
done(null, accessToken /*, params */)
})
}
},
exchange: {
code: function (client, code, redirectUri, done) {
AccessToken.create(client, code, redirectUri, function (err, accessToken) {
if (err) { return done(err) }
done(null, accessToken /*, refreshToken, params */)
})
},
credentials: function (client, scope, done) {
AccessToken.create(client, scope, function (err, accessToken) {
if (err) { return done(err) }
done(null, accessToken /*, refreshToken, params */)
})
},
owner: function (client, username, password, scope, done) {
AccessToken.create(client, username, password, scope, function (err, accessToken) {
if (err) { return done(err) }
done(null, accessToken /*, refreshToken, params */)
})
},
refresh: function (client, refreshToken, scope, done) {
AccessToken.create(client, refreshToken, scope, function (err, accessToken) {
if (err) { return done(err) }
done(null, accessToken /*, refreshToken, params */)
})
}
}
}
})
Osprey will automatically block requests with invalid scopes, when defined in RAML using the inline option syntax.
/example:
securedBy: [oauth_2_0: { scopes: [ ADMINISTRATOR ] } ]
To implement scope validation in your own application, without RAML, use osprey.security.scope('example') and users without the
required scope will be rejected.
https://github.com/mulesoft/osprey 8/10
7/8/24, 11:46 AM GitHub - mulesoft/osprey: Generate Node.JS API middleware from a RAML definition
Please note: OAuth 2.0 does not (currently) take into account security scheme describedBy of specification.
OAuth 1.0
Coming soon...
Basic Authentication
Provided by Passport-HTTP.
securitySchemes:
- basic_auth:
type: Basic Authentication
Digest Authentication
Provided by Passport-HTTP.
securitySchemes:
- digest_auth:
type: Digest Authentication
To register a custom security scheme, you can pass in your own function.
https://github.com/mulesoft/osprey 9/10
7/8/24, 11:46 AM GitHub - mulesoft/osprey: Generate Node.JS API middleware from a RAML definition
securitySchemes:
- custom_auth:
type: x-custom
The function must return an object with a handler and, optionally, a router. The router will be mounted immediately and the handler will
be called on every secured route with the secured by options and the RAML path.
Proxy
osprey.proxy(middleware, addresses)
Releases 19
+ 18 releases
Packages
No packages published
Contributors 24
+ 10 contributors
Languages
JavaScript 100.0%
https://github.com/mulesoft/osprey 10/10