npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@apparts/model-api

v4.2.1

Published

Generate CRUDish API-endpoints for a model defined with the @apparts/model package

Downloads

14

Readme

#+TITLE: @apparts/model-api #+DATE: [2021-02-08 Mon] #+AUTHOR: Philipp Uhl

Generate CRUDish API-endpoints for a model defined with the [[https://github.com/apparts-js/apparts-model][@apparts/model]] package.

  • Installation

#+BEGIN_SRC js npm i --save @apparts/model-api #+END_SRC

  • Usage

To generate CRUD-like API-endpoints for a model, use the =addCrud= function.

  • =addCrud({ prefix, app, model, routes })=
    • =prefix : string= :: The prefix for the URI, can contain parameters (see next section).
    • =app : App= :: The express app
    • =model : function= :: A function that returns an array in the form of =[OneModel, ManyModel, NoneModel]= (as does the =makeModel= function from [[https://github.com/apparts-js/apparts-model][@apparts/model]] package).
    • =routes : object= :: An object that contains options for the routes to be generated. If one of the keys is not present in the object, that route will not be generated. Possible keys are:
      • =get= :: The get all route
      • =getByIds= :: The get by ids route
      • =post= :: The create item route
      • =put= :: The update item route
      • =patch= :: The patch item route
      • =delete= :: The delete items route The values for each of these keys are objects, that can contain:
      • =hasAccess : (request) -> Promise= :: A functions that defines access rights for the individual endpoint. It receives the same parameters as a request handler from [[https://github.com/apparts-js/apparts-types][@apparts/types]] receives. If the function throws an HttpError (from [[https://github.com/apparts-js/apparts-prep][@apparts/prep]]), access will be rejected. If another error is thrown, a 500 error will be produced. Otherwise access will be granted.
      • =title : string= :: A custom title for the documentation
      • =description : string= :: A custom description for the documentation
    • =idField?: string= :: (optional, default value is =id=) When using a field for identifying, named different than =id=, you must specify the fields name using this parameter. This also changes the routes to use the =idField='s value instead of =id= and =(idField + 's')= for the pluralizations of =id= (e.g. =GET /v/1/user/:customIds= for =idField= of =customId=).

#+BEGIN_SRC js const { addCrud, anybody } = require("@apparts/model-api");

const addRoutes = (app) => { // ...add your routes

addCrud("/v/1/user", app, useUser, { get: anybody, getByIds: anybody, post: anybody, put: anybody, patch: anybody, delete: anybody, }); }; #+END_SRC

Adds these routes:

  • =GET /v1/user= :: The get all route (=get=)
  • =GET /v/1/user/:ids= :: The get by ids route (=getByIds=)
  • =POST /v/1/user= :: The create item route (=post=)
  • =PUT /v/1/user/:id= :: The update item route (=put=)
  • =PATCH /v/1/user/:id= :: The patch item route (=patch=)
  • =DELETE /v/1/user/:ids= :: The delete items route (=delete=)

All these routes have access control defined by you through the =access= parameter when defining the routes.

** Custom route prefixes for more REST-style access

#+BEGIN_SRC js const { addCrud, anybody } = require("@apparts/model");

// create comment model with this type: const types = { id: { type: "id", public: true,
auto: true,
key: true }, userid: { type: "id", public: true }, createdOn: { type: "time", default: (c) => c.optionalVal || Date.now() }, comment: { type: "string", public: true }, };

// add routes addCrud("/v/1/user/:userid/comment", app, useComments, { get: { hasAccess: anybody }, getByIds: { hasAccess: anybody }, post: { hasAccess: anybody }, put: { hasAccess: anybody }, patch: { hasAccess: anybody }, delete: { hasAccess: anybody }, }); #+END_SRC

Adds these routes:

  • =GET /v/1/user/:userid/comment=
  • =GET /v/1/user/:userid/comment/:ids=
  • =POST /v/1/user/:userid/comment=
  • =PUT /v/1/user/:userid/comment/:id=
  • =PATCH /v/1/user/:userid/comment/:id=
  • =DELETE /v/1/user/:userid/comment/:ids=

Note, that the parameter =userid= from the route is /automatically/ /matched/ against the =userid= field from the model.

** Access management

In the previous examples, all routes where created accessible for anybody. That is most likely not what you want. Instead, you can define a function for each crud operation that decides if access should be granted. This function receives all parameters of the API-call and uses them to determine if access should be granted.

To learn more about the access function and how to use it, visit [[https://github.com/apparts-js/apparts-prep#access-control][@apparts/prep - Access Control]].

** Special parameters in the model

When defining the type of your model, you can use all the parameters as defined by [[https://github.com/phuhl/apparts-model][@apparts/model]] (e.g. =public=, =mapped=, =optional=, =derived=, =auto=). The generated API endpoints respect these values:

  • Only types with =public: true= are shown on GET and can be set with POST and PUT
  • Types with =mapped: true= are shown to the outside with their mapped names
  • Types with =optional: true= are optional and don't have to be set
  • Types with =auto= or a =derived= function can not be set on PUT or POST
  • The =derived= function can be used to fetch sub object as the =derived= function is called asynchronously.

Additionally, @apparts/model-api respects the value =readOnly=:

  • Types with =readOnly: true= can only be read. It's value have to be created with a =default= function. This can be useful, e.g. for a created date, that should be readable (i.e. public) but not be modifiable.